# YouTube Scraper (`nokia2k/youtube-all-in-one-scraper`) Actor

YouTube scraper for video data in one row: views, exact likes and date, top comments, chapters, channel subscribers and the transcript. Takes videos, channels, playlists or keyword searches. No YouTube API key. Missing or private videos are free. $4.99 per 1,000 on Free, from $2.49 on paid plans.

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

## Pricing

from $2.49 / 1,000 videos

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

**A YouTube scraper that gives one row per video with everything YouTube shows about it: the full transcript, exact views, likes and publish date, the comment count and top comments, chapters, most replayed moments, hashtags and the channel's facts, for videos, channels, playlists or searches.**

**$4.99 per 1,000 videos on Apify's Free plan, down to $2.49 on paid plans** (prices at the time of writing): half a cent or less each.

**Videos that do not exist, are private or could not be reached are never charged, and every row's `charged` field shows what was billed.**

🇪🇸 [Guía completa en español](#guia-completa-en-espanol)

### What does YouTube Scraper do?

This YouTube scraper is an Actor (Apify's word for a ready-made tool that runs in the cloud) made for analysts, agencies, researchers and creators who study what works, and who do not want one tool for transcripts, a second for statistics and a third for comments. Paste video, channel or playlist links, or type a search, and press **Start**. You pay per video that comes back with data: a video without captions still brings its numbers, chapters and comments, so it is charged unless you switch the details off. There is nothing to set up: no YouTube API key, no login, no proxy.

#### Why people pick it

- **Transcript, statistics and comments in the same row,** already matched to each other. No joining three spreadsheets by hand.
- **Everything YouTube shows:** exact publish date, likes, comment count, category, hashtags, links in the description, chapters, most replayed moments (once a video has enough views), music credits, YouTube's AI summary when it exists, blocked countries, related videos, and the channel's handle, subscribers and verified badge.
- **Top comments with their context:** up to 100 per video, with author, likes, number of replies, pinned and hearted. The **Comments** view turns them into a table of their own.
- **Honest numbers.** Each number is marked exact or rounded by YouTube, and the rounded ones come with the text YouTube printed. `detailsMissing` says when a part did not arrive; gaps are never filled with guesses.
- **Videos, channels, playlists and searches in one form,** with **Only new videos since the last run** for scheduled monitoring.
- **A clear bill.** Every row says `charged: true` or `charged: false`, and the last message of the run gives the total.

#### Measured speed and reliability

- **Speed.** Measured on the Apify platform on 7–8 October 2026, as the total run time from start to finish: **5 videos with all details and 5 comments each took 4.6 seconds.** The transcript, the details and the comments of a video are requested at the same time, and 40 videos are worked on at once. Your times will vary a little with YouTube and with the videos.
- **Reliability of the transcript part.** In a test on 8 October 2026, 3,629 videos from 20 channels in two runs gave 3,447 transcripts, 171 videos without captions, 10 age-restricted videos and 1 video that failed on a timeout (0.03 %). None was blocked by YouTube. A set of 25 difficult videos (no captions, live, age-restricted, private, deleted, paid, blocked in the US, a 5-hour video, Japanese, Korean, Spanish, Shorts) all got the right answer.
- **A run does not break.** It ends as **Succeeded** with one row per entry that says what happened. An unexpected problem becomes a row with `status: "error"` instead of a failed run, so an automation keeps going.
- **Time limits.** Each video has 30 seconds in total and each request 25 seconds. A run with a **Timeout** stops taking new videos shortly before the limit, ends normally and says how many videos were not processed. Those are not charged.
- **Before giving up,** two separate app identities and three kinds of connection (home addresses, datacenter addresses and the server's own address) are tried before a video is reported as `blocked` or `error`. If Apify moves the run to another server, it continues where it stopped and never charges a video twice.

### Quick start: scrape YouTube video data in 5 steps

Apify is the website that runs this tool. You need a free Apify account and about five minutes.

1. **Create a free account.** Open `https://console.apify.com/sign-up`. Type your email and a password of 8 characters or more and click **Sign up**, or click **Continue with Google**. With email you receive a message with a link: click it.
   - *You see:* Apify Console, the web panel of your account. The free plan gives you $5 of credit every month and asks for no credit card.
2. **Open this Actor.** Go to `https://apify.com/nokia2k/youtube-all-in-one-scraper` and click **Try for free**. Sign in if you are asked. If you do not see a form, use the left menu **Apify Store**, search for `nokia2k youtube-all-in-one-scraper` and click it.
   - *You see:* the **Input** tab. The first box, **📺 Videos, channels or playlists**, already holds one example video. The form is pre-filled to add 5 top comments to the row.
3. **Paste your links** in place of the example, one per line: videos, channels or playlists. Change nothing else for now.
4. **Click Start.**
   - *You see:* the **run** (one execution of the Actor) begins. A few seconds later its status reads **Succeeded**.
5. **Open the Output tab, click Export, choose a format and click Download.** Excel, CSV, JSON and more; **Preview** shows the result first.
   - *You see:* first a table with one row per video: thumbnail, title, status, language, transcript, channel, views, publish date, likes, comments and subscribers. This table is the **dataset**. After **Download** the file is where your browser keeps its downloads.

The smallest input, in JSON (the **Input** tab has a switch between the form and JSON):

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

Two things to know before your first Excel or CSV file:

- A spreadsheet cell cannot hold a list, so lists such as `segments` (the caption lines) and `comments` are spread over many columns, and these formats stop at 2,000 columns. In the export window, type `segments` and `comments` into **Omit fields**. The transcript is still there as `text`, and the comments have their own table (see [Export the comments as their own table](#export-the-comments-as-their-own-table)).
- To find your results later, use the left menu **Runs**, or **Storage** and then the **Datasets** tab. On the free plan, results without a name are deleted after 7 days. To keep them, open the dataset, open the **Actions** menu and click **Rename**.

### What data do you get from each video?

The results of a run are stored in a **dataset**, a table kept on Apify. Each video is one row. A row has up to 74 fields, grouped below. A field shows `null` (empty) when YouTube has no such value for the video, and an empty list `[]` when the page was read and there is nothing to list.

The words "exact" and "rounded" are used strictly. **Exact** means YouTube gave the full number. **Rounded** means YouTube only publishes an abbreviation such as "27.9M", so the number in the row is 27,900,000 and the text YouTube printed is kept in a second field.

#### Video

| Field | Meaning | Example |
| --- | --- | --- |
| `videoId`, `url` | The 11-character ID and the standard link. | `arj7oStGLkU` |
| `title`, `description` | The title and the text under the video. | `Inside the Mind of a Master Procrastinator \| Tim Urban \| TED` |
| `keywords`, `hashtags` | Tags set by the uploader; hashtags shown above the title and in the description, each once. | `["#TED"]` |
| `descriptionLinks` | Every link in the description, as `text` and `url`, with YouTube's redirect removed. Links that only jump to another moment of the same video are left out. | `[{"text": "ted.com", "url": "https://www.ted.com"}]` |
| `thumbnailUrl` | Link to the largest preview picture YouTube returns. | |
| `category` | YouTube's category. | `People & Blogs` |
| `publishedAt` | Exact date and time of publication, in UTC (ISO 8601 ending in `Z`). If YouTube gives only the day, the value is the date alone. | `2016-04-06T16:59:35Z` |
| `uploadedAt` | Exact date and time the file was uploaded, in UTC. It can be earlier than the publish date. | |
| `publishedDateText` | The date as YouTube prints it under the video. | `Apr 6, 2016` |
| `isShort`, `isLive`, `isLiveNow` | A Short; a live stream or its recording; a stream on air now. | `false` |
| `liveStartedAt`, `liveEndedAt` | For streams and their recordings: when the stream started and ended. | `null` |
| `isUnlisted`, `isFamilySafe`, `isMembersOnly`, `isPaid` | YouTube's flags: reachable by link only; family-safe; for channel members; tied to a purchase, rental or membership. | `false` |
| `blockedCountries`, `availableCountries` | Country codes where the video is blocked (`[]`: watchable everywhere); where it can be watched (filled only when that list is shorter). | `[]` |
| `music`, `musicTracks` | Song, artist and album when YouTube credits music; all credited tracks when there are several. | `null` |
| `aiSummary` | The AI-written summary YouTube shows under some videos. Only when YouTube shows one for the video, which is rare; `null` otherwise. | `null` |
| `relatedVideos` | Up to 10 videos YouTube suggests next, each with its video ID and title. | 10 items |

#### Numbers

| Field | Meaning | Exact or rounded | Example |
| --- | --- | --- | --- |
| `durationSeconds` | Length of the video in seconds. | Exact. | `844` |
| `viewCount` | Views at the moment of the run. | Exact. | `62013820` |
| `likeCount` | Likes. `null` when the owner hides them. | Exact. | `2054977` |
| `commentCount` | Number of comments. | Exact when `maxComments` is 1 or more. With `maxComments` at 0 it is YouTube's rounded figure ("79K" becomes 79000). | `79650` |
| `commentCountText` | The comment count as YouTube prints it. | Text, as shown. | `79,650 Comments` |
| `liveViewers` | People watching a stream that is on air. | As shown at that moment. | `null` |

Two more numbers live in other groups: `channelSubscribers` is always rounded, and the `likes` of a comment are exact below 1,000 and rounded above. Dislikes are not available: YouTube no longer shows them.

#### Channel

| Field | Meaning | Example |
| --- | --- | --- |
| `channelName`, `channelId` | Name and YouTube's ID of the channel. | `TED`, `UCAuUUnT6oDeKwE6v1NGQxug` |
| `channelHandle`, `channelUrl` | The channel's @handle and link. | `@TED` |
| `channelSubscribers` | Subscribers. **Rounded by YouTube to three digits**: "27.9M" becomes 27900000. The exact count is not public. | `27900000` |
| `channelSubscribersText` | The subscriber count as YouTube prints it. | `27.9M subscribers` |
| `channelVerified` | `true` when the channel has a verified badge. | `true` |
| `channelAvatar` | Link to the channel's profile picture. | a link |

#### Chapters and most replayed moments

| Field | Meaning | Example |
| --- | --- | --- |
| `chapters` | The chapters of the video: `title`, `start` in whole seconds and `startText` as YouTube shows it. The creator's own chapters are used; when there are none, the ones YouTube generated. `[]` when the video has no chapters. | `[{"title": "The life calendar", "start": 756, "startText": "12:36"}]` |
| `chaptersAreAuto` | `true` when YouTube created the chapters itself, `false` when the creator wrote them. | `true` |
| `mostReplayed` | The moments viewers replay most, strongest first, at most five. Each has `start` and `end` in seconds, `intensity` and `labeled` (`true` when YouTube itself marks the moment "Most replayed"). **`intensity` is a relative score from 0 to 1, not a count**: 1 is the most replayed part of this video. It is filled only when YouTube shows the "Most replayed" graph for the video, which it does once enough people have watched it: videos with few views, many videos only a few days old, very long videos and streams have no replay data (`null`). | `[{"start": 481.08, "end": 489.52, "intensity": 1}]` |

#### Comments

| Field | Meaning | Example |
| --- | --- | --- |
| `comments` | The top comments, in the order YouTube shows them, up to `maxComments`. `null` when no comments were requested. | see the sample |
| `commentsDisabled` | `true` when the uploader turned comments off, `false` when the comment section is there, `null` when the page does not say (for example a stream on air). | `false` |

Each comment has these parts:

| Part | Meaning | Exact or rounded |
| --- | --- | --- |
| `id` | YouTube's ID of the comment. | |
| `text` | The comment. | |
| `author` | The author's @handle. | |
| `likes` | Likes of the comment. | **Exact below 1,000. Above that YouTube only shows "3.2K", which becomes 3200.** |
| `likesText` | The likes as YouTube prints them. | Text, as shown (`3.2K`). |
| `replyCount` | Number of replies. | Exact. |
| `publishedText` | Age of the comment as shown. | Rough (`7 years ago`). |
| `isPinned`, `isHearted` | `true` when the creator pinned it, or gave it a heart. | |
| `authorIsChannelOwner` | `true` when the creator wrote it. | |

#### Transcript

| Field | Meaning | Example |
| --- | --- | --- |
| `language`, `languageName` | Code and name of the language you received. | `en`, `English` |
| `isAutoGenerated` | `true` when the captions come from YouTube's speech recognition, `false` when a person wrote them. | `false` |
| `isTranslated`, `translatedFrom` | Whether it is YouTube's machine translation, and from which language. | `false`, `null` |
| `availableLanguages` | Every caption language the video has: `code`, `name`, `isAutoGenerated`, `isTranslatable`. | |
| `segmentCount`, `wordCount`, `charCount` | Caption lines (or blocks), words and characters. Counted exactly. | `315`, `2277`, `12671` |
| `text` | The whole transcript as one paragraph. With the `text` format. | `So in college, I was a government major…` |
| `timestampedText` | One line per caption: `[MM:SS] text`. | `[00:01] All right, so here we are…` |
| `segments` | Caption lines with `start`, `duration` and `end` in seconds and their `text`. | |
| `srt`, `vtt` | The content of an `.srt` or `.vtt` subtitle file. | |
| `markdown` | The transcript as a Markdown document with title, channel, date and link. | |
| `files` | Download links of the saved files, by format. With `saveFiles` on. | |
| `data` | Caption lines as `start`, `dur` and `text` strings. Only when the input used the single `videoUrl` field. | |

#### Source and bookkeeping

| Field | Meaning | Example |
| --- | --- | --- |
| `source`, `sourceType`, `sourceTitle` | The channel, playlist or search a video came from: link or search words, `channel`/`playlist`/`search`, and its name. | `https://www.youtube.com/@TED`, `channel`, `TED` |
| `positionInSource` | Place of the video in that list, starting at 1. Exact. | `1` |
| `publishedText` | The age of the video as YouTube's list shows it. Rough: use `publishedAt` for the exact date. | `2 hours ago` |
| `input` | The value from your input that produced this row. Rows arrive in the order they finish. | `https://www.youtube.com/watch?v=arj7oStGLkU` |
| `status` | What happened with the **transcript** of this video. | `success` |
| `message` | A plain-language explanation when the status is not `success`, or a note such as a language fallback. | (empty) |
| `charged` | `true` when this row was billed. | `true` |
| `detailsMissing` | Parts of the details YouTube did not answer this time. `[]` when everything arrived. | `[]` |
| `scrapedAt` | When the row was produced, in UTC. | `2026-10-08T09:00:00+00:00` |

#### Sample output: one success row and one no_captions row

The example video of the form, requested with the `text` format and one comment. Shortened: long texts end in "…", and some fields are left out. Values read on 8 October 2026.

```json
{
    "videoId": "arj7oStGLkU",
    "url": "https://www.youtube.com/watch?v=arj7oStGLkU",
    "status": "success",
    "message": "",
    "charged": true,
    "detailsMissing": [],
    "title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED",
    "category": "People & Blogs",
    "publishedAt": "2016-04-06T16:59:35Z",
    "isShort": false,
    "isLive": false,
    "durationSeconds": 844,
    "viewCount": 62013820,
    "likeCount": 2054977,
    "commentCount": 79650,
    "commentsDisabled": false,
    "channelName": "TED",
    "channelId": "UCAuUUnT6oDeKwE6v1NGQxug",
    "channelHandle": "@TED",
    "channelUrl": "https://www.youtube.com/@TED",
    "channelSubscribers": 27900000,
    "channelSubscribersText": "27.9M subscribers",
    "channelVerified": true,
    "chapters": [
        { "title": "My procrastination journey", "start": 0, "startText": "0:00" },
        { "title": "The procrastinator's brain", "start": 176, "startText": "2:56" },
        { "title": "The monkey and the playground", "start": 249, "startText": "4:09" },
        { "title": "The role of the panic monster", "start": 436, "startText": "7:16" },
        { "title": "Two types of procrastination", "start": 599, "startText": "9:59" },
        { "title": "The life calendar", "start": 756, "startText": "12:36" }
    ],
    "chaptersAreAuto": true,
    "mostReplayed": [
        { "start": 481.08, "end": 489.52, "intensity": 1 },
        { "start": 16.88, "end": 25.32, "intensity": 0.951 }
    ],
    "comments": [
        {
            "text": "He procrastinated in creating a Ted talk about procrastination. Ted definitely picked the right man for the job.",
            "author": "@SWIFTzTrigger",
            "likes": 3200,
            "likesText": "3.2K",
            "replyCount": 2,
            "publishedText": "7 years ago"
        }
    ],
    "language": "en",
    "languageName": "English",
    "isAutoGenerated": false,
    "isTranslated": false,
    "translatedFrom": null,
    "segmentCount": 315,
    "wordCount": 2277,
    "charCount": 12671,
    "text": "So in college, I was a government major, which means I had to write a lot of papers. …",
    "input": "https://www.youtube.com/watch?v=arj7oStGLkU",
    "scrapedAt": "2026-10-08T09:00:00+00:00"
}
```

Read it as a check of the rules above: `likeCount` and `viewCount` are exact, `commentCount` is exact because a comment was requested, `channelSubscribers` is rounded, and the comment's `likes` are rounded because they are above 999.

A video without captions in the same run. The ID and the title are placeholders, and the detail fields (date, likes, comments, chapters and the rest) are filled as for any video and left out here. Because its details arrived, the row is charged:

```json
{
    "videoId": "<11-character ID>",
    "url": "https://www.youtube.com/watch?v=<11-character ID>",
    "status": "no_captions",
    "message": "The video has no captions, neither uploaded nor auto-generated.",
    "title": "<title of the video>",
    "language": null,
    "availableLanguages": [],
    "wordCount": 0,
    "detailsMissing": [],
    "charged": true
}
```

With **📊 Video and channel details** turned off, the same row would carry no details and say `charged: false`.

#### Five views of the same data

A **view** is a ready-made selection of columns. On the **Output** tab you can choose between the views of this Actor. They show the same rows in different ways and cost nothing.

| View | What it shows |
| --- | --- |
| **Overview** | Thumbnail, title, status, language, auto-generated, duration, words, transcript, channel, views, found in, published, likes, comments, subscribers, video link, message. |
| **Subtitle files** | Video ID, title, language, SRT, WebVTT. |
| **Languages** | Video ID, title, status, returned language, language name, auto-generated, translated, available languages. |
| **Video details** | The statistics table, with no transcript in the way: title, channel name, channel handle, subscribers, published at, views, likes, comments, category, duration (seconds), Short, hashtags, video URL. |
| **Comments** | One comment per row: video ID, video title, author, comment, likes, replies, when. |

**Video details** is the table an analyst usually wants first: one line per video, numbers only.

#### Export the comments as their own table

1. Open the run and its **Output** tab.
2. Choose the **Comments** view. The table now shows one comment per row, with the video ID and title repeated on every line.
3. Click **Export**, choose Excel or CSV, and click **Download**. If the export window lets you choose a view, keep **Comments**.

You can also download the same table with a direct link. Open the run's **Storage** tab, look at **Dataset** and copy the dataset ID. Then open this address in your browser, with your ID in place of `<DATASET_ID>`:

```text
https://api.apify.com/v2/datasets/<DATASET_ID>/items?view=comments&format=xlsx&clean=true
```

Use `format=csv` for a CSV file. If the address answers that you have no access, add `&token=<YOUR_APIFY_TOKEN>` to its end. Both tables carry `videoId`: that is the key that links a comment to its video in a spreadsheet or a database.

#### When a part of the details is missing

The details of a video are read in up to three parts, at the same time as the transcript. If one part does not answer, the others are still delivered, and `detailsMissing` names the part that is absent. The Actor never fills a gap with a guess: the fields of a missing part are `null`.

| Value in `detailsMissing` | What did not arrive | Fields that are empty because of it |
| --- | --- | --- |
| `microformat` | The page's fact sheet. | `uploadedAt`, `category`, `isShort`, `isUnlisted`, `isFamilySafe`, `isPaid`, the country lists, the live start and end times. `publishedAt` then holds the day only, taken from the date printed under the video when it can be read. Views and likes are still exact: they are read from the other part. |
| `watch` | The watch page. | `hashtags`, `descriptionLinks`, `chapters`, `mostReplayed`, `music`, `aiSummary`, `relatedVideos`, `publishedDateText`, `isMembersOnly`, `commentsDisabled`, `channelSubscribers`, `channelVerified`, `channelAvatar`. |
| `comments` | The comment list, or its later pages. | `comments` is `null`, or shorter than you asked for. |

What to do: run that video again. A second run is a second charge if it delivers data. A row with a missing part is still charged when the rest arrived, so check `detailsMissing` before you rely on an empty field. For a private or deleted video the list is `[]`: nothing is missing, there is simply nothing to read, and the row is free.

### Use cases

- **Find out why some videos win:** compare views, likes, comments, chapters and most replayed moments of a channel's videos side by side.
- **Read the audience, not just the video:** export the top comments of every video as their own table for sentiment and question mining.
- **Audit a competitor's channel** in one run: what they say (transcript), how it performs (numbers) and how people react (comments).
- **Track a topic every week:** a scheduled search with only new videos delivers the fresh videos with their statistics and comments.
- **Build a dataset for research or a dashboard** with exact dates, exact views and likes, and the rounding of YouTube marked where it applies.
- **Brief a client in minutes:** turn a list of influencer videos into one spreadsheet with transcript, reach and audience reaction.

### Ready-made examples: open one and press Start

Every example is a setup that was tested before it was published, with its own page and sample results. Press **Run example**, then replace the links or search terms with yours.

- [Scrape a YouTube video's likes, comments and transcript](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/scrape-a-youtube-video-s-likes-comments-and-transcript)
- [Export the top 100 comments of a YouTube video](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/export-the-top-100-comments-of-a-youtube-video)
- [Track competitor YouTube channels: views, likes, topics](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/track-competitor-youtube-channels-views-likes-topics)
- [Get YouTube chapters and most replayed moments](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/get-youtube-chapters-and-most-replayed-moments)
- [Find YouTube influencers in a niche by keyword](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/find-youtube-influencers-in-a-niche-by-keyword)
- [YouTube channel stats: views, likes and comments per video](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-channel-stats-views-likes-and-comments-per-video)
- [YouTube comments for sentiment analysis](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-comments-for-sentiment-analysis)
- [YouTube Shorts scraper with views and likes](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-shorts-scraper-with-views-and-likes)
- [YouTube keyword research: top videos with stats](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-keyword-research-top-videos-with-stats)
- [YouTube video description links and hashtags scraper](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-video-description-links-and-hashtags-scraper)

### Input examples

#### Every input field

The fields are listed in the order of the form. You need at least one link in the first box or one line in the search box. Everything else has a default.

**Videos, language and formats**

| Field in the form (JSON name) | What it is | When to touch it | Example |
| --- | --- | --- | --- |
| **📺 Videos, channels or playlists** (`urls`) | YouTube links, one per line. A video link gives that video. A channel link or a plain `@name` gives the channel's videos, newest first. A playlist link gives the playlist's videos in playlist order. Watch, `youtu.be`, Shorts, live and embed links work, and so does an 11-character video ID. A link pasted twice is fetched and charged once. | Always, unless you search instead. | `https://www.youtube.com/@TED` |
| **🔢 Videos per channel or playlist** (`maxVideosPerSource`) | How many videos to take from each channel or playlist. Default 50, from 1 to 5,000. The form is pre-filled with 5. | Start small, then raise it. | `30` |
| **🌐 Transcript language** (`languages`) | Leave it on **Original language** and each video comes back in the language it is spoken in. Or pick languages in order of preference: the first one the video has is used. 70 languages in the list; you can also type a code (`pt-BR`) or a name (`Spanish`, `español`, `Deutsch`). | When you need one specific language. | `["es", "en"]` |
| **📄 Output formats** (`outputFormats`) | `segments`, `text`, `timestampedText`, `srt`, `vtt`, `markdown`. Default: `segments` and `text`. Extra formats cost nothing. | Pick only what you use: rows get smaller and exports faster. | `["text"]` |
| **📚 Also give me everything as one Markdown file** (`combinedFile`) | Saves all transcripts of the run in `ALL_TRANSCRIPTS.md` (run's **Storage** tab, **Key-value store**). Large runs are split into files of about 8 MB. Off by default. | To upload everything to ChatGPT, Claude, NotebookLM or a knowledge base in one go. | `true` |
| **💾 Also save subtitle files I can download** (`saveFiles`) | One file per video for each text format you selected (`.srt`, `.vtt`, `.txt`), with download links in `files`. Off by default. | When you need real subtitle files. | `true` |

**Details and comments**

| Field in the form (JSON name) | What it is | When to touch it | Example |
| --- | --- | --- | --- |
| **📊 Video and channel details** (`includeDetails`) | Adds everything beyond the transcript (date, likes, comment count, chapters, most replayed, hashtags, channel facts and the rest). On by default. | Turn it off only if you want the transcript alone. With it off, no comments are fetched either, and only rows with a transcript are charged. | `true` |
| **💬 Top comments per video** (`maxComments`) | How many top comments to add to each row, from 0 to 100. Default 20; the form is pre-filled with 5. Replies themselves are not fetched. | Raise it to study the audience; 0 for none. With 1 or more, `commentCount` is exact. | `50` |

**Search instead of links**

| Field in the form (JSON name) | What it is | When to touch it | Example |
| --- | --- | --- | --- |
| **🔎 What to search for** (`searchQueries`) | What you would type into YouTube's search box, one search per line. For each search you get the videos YouTube ranks highest. Search returns regular videos, not Shorts, channels or playlists. | When you have a topic, not links. | `how to learn spanish` |
| **🔢 Videos per search** (`maxVideosPerSearch`) | Default 10, up to 500. The form is pre-filled with 5. | For a wider sample. | `20` |
| **📅 Uploaded** (`searchUploadDate`) | YouTube's own filter: `any`, `hour`, `today`, `week`, `month`, `year`. | To study recent videos only. | `month` |
| **⏱️ Length** (`searchDuration`) | YouTube's own filter: `any`, `short` (under 4 minutes), `medium` (4 to 20), `long` (over 20). | To leave out clips or long talks. | `medium` |
| **↕️ Order** (`searchSortBy`) | `relevance` is YouTube's order. `date` and `views` put the videos that were found in that order; they do not find the newest or most viewed of all YouTube. | Combine `date` with **📅 Uploaded**. | `views` |
| **Only videos that have captions (recommended)** (`onlyWithCaptions`) | YouTube's filter for captions supplied by the uploader. On by default, so videos with only automatic captions are left out. | Turn it off to include them, or videos without captions that you want for their numbers and comments. | `false` |

**Channel and playlist filters**

| Field in the form (JSON name) | What it is | When to touch it | Example |
| --- | --- | --- | --- |
| **📅 Only videos newer than** (`newerThan`) | A date, or an age such as `30 days` or `6 months`. Empty means no limit. Approximate: YouTube's lists show ages only roughly ("3 weeks ago"), so nothing newer is ever left out and a few videos just past the limit can slip in. | For "what did this channel publish lately". | `30 days` |
| **Only new videos since the last run** (`onlyNewVideos`) | For scheduled runs: each run delivers only videos it has not delivered before for the same channels, playlists and searches. Off by default. | See [Run it on a schedule](#run-it-on-a-schedule-and-get-only-new-videos). | `true` |
| **Memory name** (`memoryName`) | Optional, used only with the field above: the name of the list of delivered videos. | To keep one list even when the links change. | `"competitors-weekly"` |
| **🎞️ Kinds of videos to take from a channel** (`contentTypes`) | `videos`, `shorts`, `streams`. All three by default. Applies to channels, not playlists. | Untick what you do not need. | `["videos"]` |

**More options**

| Field in the form (JSON name) | What it is | When to touch it | Example |
| --- | --- | --- | --- |
| **🔁 Translate to** (`translateTo`) | YouTube's own machine translation, used when the video has no captions in that language. Not offered for every video: then you get the original language and a note in `message`. | Every transcript in one language. | `es` |
| **If my language is missing, give me the original language** (`fallbackToAnyLanguage`) | On by default. Off: no transcript for videos without your languages (`language_unavailable`). | When another language is useless to you. | `false` |
| **Caption type** (`captionType`) | `any` (human-made first), `manual` (human-made only) or `auto` (auto-generated only). | `manual` when punctuation and names matter. | `manual` |
| **Merge caption lines into blocks** (`mergeSegmentsSeconds`) | Joins caption lines into blocks of about this many seconds, 0 to 3,600. 0 keeps the original lines. This is chunking for RAG and vector databases: each block is one RAG chunk with its start and end time. | For search indexes, RAG chunks and vector databases. | `30` |
| **Include video details** (`includeMetadata`) | The basic facts that come with the transcript: channel, duration, view count, description, keywords and thumbnail. On by default. | Rarely. Leave it on. | `true` |

#### One video with everything and 20 comments

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

#### A batch of videos

```json
{
    "urls": [
        "https://www.youtube.com/watch?v=arj7oStGLkU",
        "https://youtu.be/jNQXAC9IVRw"
    ],
    "outputFormats": ["text"],
    "maxComments": 10
}
```

#### The 30 newest regular videos of a channel, with 50 comments each

```json
{
    "urls": ["https://www.youtube.com/@TED"],
    "maxVideosPerSource": 30,
    "contentTypes": ["videos"],
    "outputFormats": ["text"],
    "maxComments": 50
}
```

#### A playlist, transcripts translated into Spanish

```json
{
    "urls": ["https://www.youtube.com/playlist?list=PLxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
    "maxVideosPerSource": 100,
    "translateTo": "es",
    "outputFormats": ["text"],
    "maxComments": 0
}
```

#### A topic instead of links: this month's top 20 of two searches

```json
{
    "searchQueries": ["how to learn spanish", "iphone 17 review"],
    "maxVideosPerSearch": 20,
    "searchUploadDate": "month",
    "onlyWithCaptions": false,
    "outputFormats": ["text"],
    "maxComments": 10
}
```

#### A channel's last 30 days

```json
{
    "urls": ["https://www.youtube.com/@TED"],
    "maxVideosPerSource": 200,
    "newerThan": "30 days",
    "outputFormats": ["text"],
    "maxComments": 20
}
```

#### Only new videos of competitors' channels, for a weekly schedule

```json
{
    "urls": ["https://www.youtube.com/@TED", "@anotherchannel"],
    "maxVideosPerSource": 30,
    "onlyNewVideos": true,
    "memoryName": "competitors-weekly",
    "outputFormats": ["text"],
    "maxComments": 20
}
```

### Run it on a schedule and get only new videos

Follow channels, playlists or searches and get each new video once, with its numbers and comments.

#### How "Only new videos since the last run" works

- Turn on **Only new videos since the last run** (`onlyNewVideos`). It is off by default and made for scheduled runs (Apify **Schedules**).
- Each run then delivers only the videos it has not delivered before for the same channels, playlists and searches. Videos already delivered are left out **before anything is fetched**, so they are neither fetched nor charged.
- The first run delivers everything it finds and remembers it.
- Video links you paste directly are always delivered, never left out. They are remembered, so a channel or search that contains them later does not deliver them again.

#### Set it up step by step

1. **Fill the form:** your channels, playlists or searches, the numbers per source, comments and formats. Tick **Only new videos since the last run**. Optional: type a **Memory name** such as `competitors-weekly`.
2. **Click Start once by hand.** The first run delivers what it finds and remembers it. It also makes the Actor schedulable: an Actor must have run once before it can be scheduled.
3. **Click Save as a new task** at the top right of the Actor page. A **task** is a saved form; it appears under **Saved tasks**.
4. **Open Schedules** in the left menu and click **Create new**.
5. **In the Schedule setup card** choose how often (a cron expression such as `@weekly`, or the visual builder) and your time zone. **Next runs** shows the coming dates.
6. **In the Add dropdown** pick your task.
7. **Click Enable.** New schedules start disabled.

#### What you see in later runs

- The log and the run's final status message say how many videos were left out, for example: "Skipped 37 videos already delivered in earlier runs (memory 'x')."
- A run with nothing new ends normally, with no rows: "No new videos since the last run: … Nothing was charged."

#### Memory name: one list or several

- **Left empty:** the memory is named `auto-…` after your list of channels, playlists and searches. The order and the letter case of searches do not matter; any other change to the list starts a new memory.
- **With a name:** you pick the record. The same name keeps one list even when the links change; a different name keeps a separate list.
- Letters, digits and `-_.!'()` are kept; other characters become `-`.

#### Where the memory lives and how to start afresh

The memory is kept in your own Apify account: **Storage** > **Key-value stores**, in the store named `youtube-transcripts-memory`. Each memory is one record that holds the IDs of the most recent 20,000 delivered videos and the time it was last updated. Delete the record, or the whole store, and the next run starts afresh and delivers everything again.

#### Good to know

- **Remembered:** videos delivered as `success` or `no_captions`, and every row that was charged. Free rows (`blocked`, `error`, `age_restricted` without details) and a live stream that is still running or has not started are tried again next run.
- **Never charged twice:** a row can be charged for its details even when its status is not `success` or `no_captions`, for example an `age_restricted` video whose details arrived. Every charged video is remembered, so a later run with **Only new videos since the last run** never charges it again.
- **Keep the numbers high enough.** **🔢 Videos per channel or playlist** and **🔢 Videos per search** count the videos looked at in each run, before the known ones are left out. Set them above the number of new videos you expect between two runs.
- **The memory is saved at the end of the run,** also when the run stops before its time limit or at the spending cap (then only the videos that were processed). After a server move the run continues and saves at its end; nothing is counted or charged twice.
- **If the memory cannot be read,** the run logs a warning and delivers all videos like a normal run. If it cannot be saved, the results are still delivered, and the next run may repeat some videos.
- **Two runs with the same memory at the same time** can both deliver the same new video. The memory itself keeps the videos of both.

#### Send new videos to Google Sheets or Slack

- **n8n:** add the **Apify Trigger** node (**Resource to Watch**: **Task**, your task; **Event Type**: **Succeeded**). Then an **Apify** node with Resource **Dataset**, **Get Items**, and the `defaultDatasetId` of the run as **Dataset ID** (raise **Limit**: it starts at 50). Then a Google Sheets node that appends one row per item (`title`, `channelName`, `publishedAt`, `viewCount`, `likeCount`, `commentCount`, `url`), or a Slack node that posts `title` and `url`. A self-hosted n8n needs a public `WEBHOOK_URL` so that Apify can reach it.
- **Make:** start with **Watch Actor Runs** (it fires when a run finishes), then **Get Dataset Items**, then a Google Sheets module (Apify's guide uses "Bulk Add Rows") or a Slack module.
- **Any other tool:** on the task's **Integrations** tab add a webhook for the event `ACTOR.RUN.SUCCEEDED`. Apify sends a POST to your address; the dataset ID is in `resource.defaultDatasetId`. The receiver must answer within 2 minutes, and a webhook can arrive twice.

A run with no new videos still finishes as Succeeded, with an empty dataset: your sheet simply gets no new rows that time.

### Use YouTube Scraper from AI agents (MCP)

MCP is the standard that lets an AI assistant use outside tools. This address gives the assistant this Actor as a tool:

```text
https://mcp.apify.com?tools=nokia2k/youtube-all-in-one-scraper
```

Sign-in is OAuth: a browser window opens on the first connection and no token is stored in the configuration. A header `Authorization: Bearer <YOUR_APIFY_TOKEN>` works too. The assistant waits up to 45 seconds for a run and then reads the rows from the dataset, so ask for a few videos at a time. Each run costs credit on your Apify plan like any other.

#### Claude.ai and Claude Desktop

1. Open **Connectors** in Claude's settings (**Settings** > **Connectors**; Claude's help page calls the place **Customize** > **Connectors**).
2. Choose **Add custom connector**.
3. Fill **Name** and **Remote MCP server URL** with the address above, click **Continue**, then **Add**.
4. Sign in to Apify when the browser asks.
5. In a chat, click **+**, then **Connectors**, and switch it on.

On the free Claude plan you can add one custom connector. On Team and Enterprise plans an Owner adds it for the organization.

#### Claude Desktop with a local server

`claude_desktop_config.json`, needs Node.js:

```json
{
  "mcpServers": {
    "youtube-video-analytics": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--tools", "nokia2k/youtube-all-in-one-scraper"],
      "env": {
        "APIFY_TOKEN": "<YOUR_APIFY_TOKEN>"
      }
    }
  }
}
```

#### Cursor

`.cursor/mcp.json` in your project, or `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "youtube-video-analytics": {
      "url": "https://mcp.apify.com?tools=nokia2k/youtube-all-in-one-scraper"
    }
  }
}
```

With a token instead of OAuth, add `"headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }` next to `"url"`.

#### VS Code

Needs GitHub Copilot. Open the Command Palette, run **MCP: Open User Configuration** and add:

```json
{
  "servers": {
    "youtube-video-analytics": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=nokia2k/youtube-all-in-one-scraper"
    }
  }
}
```

#### Claude Code and ChatGPT

```bash
claude mcp add --transport http youtube-video-analytics \
  "https://mcp.apify.com?tools=nokia2k/youtube-all-in-one-scraper" \
  --header "Authorization: Bearer $APIFY_TOKEN"
```

**ChatGPT:** Developer mode is required. Go to **Settings > Apps & Connectors > Create**, fill **Name**, **Description** and **MCP Server URL**, keep **Authentication** on OAuth and click **Create**. In a chat, click **+**, then **More**, and pick the connector.

#### Example prompts

- "Get the transcript, likes and top 20 comments of https://www.youtube.com/watch?v=arj7oStGLkU and tell me what viewers liked most."
- "Compare the 5 newest videos of @TED: views, likes, comment count and the most replayed moment of each, in one table."
- "Read the top comments of this video and list the five questions viewers ask most often: \[link]"

### Integrations: n8n, Make, Zapier, Python, JavaScript and LangChain

You need an **API token** for most of these: a secret key that lets another program use your Apify account. Find it in Apify Console under **Settings**, then **API & Integrations**. Treat it like a password. In the examples it is written `<YOUR_APIFY_TOKEN>`.

#### API: one call with curl

```bash
curl -X POST "https://api.apify.com/v2/acts/nokia2k~youtube-all-in-one-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "outputFormats": ["text"], "maxComments": 5}'
```

It waits at most 300 seconds; a longer run answers HTTP 408, so use the two-step flow for big lists: `POST /v2/acts/nokia2k~youtube-all-in-one-scraper/runs` returns the run with its `defaultDatasetId` (add `?waitForFinish=60` to wait up to 60 seconds). Read the rows with `GET /v2/datasets/<DATASET_ID>/items?format=json&clean=true`, or the comment table with `view=comments`. A spending cap is the query parameter `maxTotalChargeUsd`.

#### Python

`pip install apify-client` (version 3, Python 3.11 or newer):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nokia2k/youtube-all-in-one-scraper").call(
    run_input={
        "urls": ["https://www.youtube.com/@TED"],
        "maxVideosPerSource": 10,
        "outputFormats": ["text"],
        "maxComments": 20,
    },
)
for row in client.dataset(run.default_dataset_id).iterate_items():
    print(
        row["status"],
        row["charged"],
        row.get("title"),
        row.get("likeCount"),
        row.get("commentCount"),
    )
```

#### JavaScript

`npm install apify-client`:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('nokia2k/youtube-all-in-one-scraper').call({
    searchQueries: ['how to learn spanish'],
    maxVideosPerSearch: 10,
    outputFormats: ['text'],
    maxComments: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) {
    console.log(row.status, row.charged, row.title, row.likeCount, row.comments?.length ?? 0);
}
```

#### LangChain

`pip install langchain-apify langchain-core`, then set `APIFY_API_TOKEN` (the variable `langchain-apify` reads):

```python
from langchain_apify import ApifyWrapper
from langchain_core.documents import Document

loader = ApifyWrapper().call_actor(
    actor_id="nokia2k/youtube-all-in-one-scraper",
    run_input={
        "urls": ["https://www.youtube.com/@TED"],
        "maxVideosPerSource": 10,
        "outputFormats": ["text"],
        "maxComments": 0,
    },
    dataset_mapping_function=lambda row: Document(
        page_content=row.get("text") or "",
        metadata={
            "source": row.get("url"),
            "title": row.get("title"),
            "likes": row.get("likeCount"),
            "status": row.get("status"),
        },
    ),
)
docs = [d for d in loader.load() if d.metadata["status"] == "success"]
```

#### n8n

1. Install the Apify node. On n8n Cloud: open the nodes panel, search **Apify** (it is under **More from the community**) and install it. On your own server: **Settings > Community Nodes**, **Install**, type `@apify/n8n-nodes-apify`.
2. Create the credential **Apify API** and paste your token into **API Key**.
3. Add an **Apify** node. Set Resource to **Actor** and Operation to **Run an Actor and Get Dataset**.
4. In **Actor**, choose YouTube Scraper.
5. In **Input JSON**, paste an input such as `{"urls": ["https://www.youtube.com/watch?v=arj7oStGLkU"], "outputFormats": ["text"], "maxComments": 20}`. Replace the link with an n8n expression that points to the link from your first node.
6. Set **Memory** to 4096. The node sends 1024 MB unless you change it, and this Actor's default is 4096 MB. Optional: **Maximum Cost per Run (USD)**.
7. Execute the node.
   - *You see:* each row as one n8n item with `text`, `likeCount`, `comments` and the rest. Connect your next node.

Two common mistakes: **Run an Actor** returns facts about the run, not the rows, so use **Run an Actor and Get Dataset**. And **Get Items** returns only 50 rows unless you raise **Limit**.

#### Make

1. Add the Apify module **Run an Actor** and create the **Connection**.
2. Choose the **Actor**, set **Run synchronously** to **Yes** and paste your input into **Input JSON**.
3. Add **Get Dataset Items**. In **Dataset ID**, map the default dataset ID (`defaultDatasetId`) from the first module. Raise **Limit** so that all rows arrive.
4. Add your destination, for example a Google Sheets module.

For runs longer than about 2 minutes, start from the trigger **Watch Actor Runs** instead: it fires when a run finishes, and **Get Dataset Items** follows it.

#### Zapier

Zapier waits at most 30 seconds for a synchronous run and then cuts it off. Use two Zaps for anything larger than a handful of videos:

1. Zap A: your trigger, then the action **Run Actor**, set to run asynchronously.
2. Zap B: the trigger **Finished Actor Run**, then **Fetch Dataset Items**, then your destination.

#### Google Sheets and Excel

- **Excel:** on the **Output** tab click **Export**, choose Excel, click **Download**.
- **Google Sheets by hand:** export as CSV or Excel and import the file in Google Sheets.
- **Google Sheets automatically:** use Make, Zapier or n8n with their Google Sheets step.
- **Google Drive:** on the Actor's **Integrations** tab choose **Upload results to GDrive**, click **Connect with Google**, set **Filename** and **Format** and click **Save**. The file lands in the folder `Apify Uploads` after each successful run.

For spreadsheets, the **Video details** and **Comments** views are the two tables to export.

### How much does it cost to scrape YouTube video data and comments?

#### The rule

**A row is charged when it carries a transcript, or the details, or both. It is charged once, never twice.** The `charged` field of every row shows the result.

- "Carries a transcript" means `status` is `success`.
- "Carries the details" means YouTube answered with at least the exact publish date, the like count or the channel's subscriber figure.
- `status` describes the transcript; `charged` describes the bill. A row can say `no_captions` and `charged: true`, because the numbers, the channel facts and the comments were delivered.

Never charged: links that are not YouTube videos, videos that do not exist, private videos, videos YouTube could not be reached for, channels, playlists or searches that could not be listed, the second copy of a link pasted twice, and videos left out because an earlier run delivered them. Also free: comments (0 or 100, the price is the same), extra output formats, saved files, the combined Markdown file and translation. If you only want to pay for videos that have a transcript, turn **📊 Video and channel details** off, or use one of the transcript tools in [Related YouTube tools](#related-youtube-tools).

#### Price and worked examples

The Actor uses **pay per event**: you pay for each result, not for time or a subscription. At the time of writing the Free plan price is **$4.99 per 1,000 videos**: each charged row costs $0.00499. On paid Apify plans it is cheaper: $4.19 (Starter), $3.49 (Scale), $2.49 (Business). On top comes Apify's start event: $0.00005 per run for each GB of memory, which is $0.0002 for a run with the default 4 GB. You pay nothing else for a normal run: no platform usage and no proxy fees. The price that counts is the one on the Actor's **Pricing** tab.

| One run with | Rows charged | Videos | Run start (4 GB) | Total |
| --- | --- | --- | --- | --- |
| 10 videos | 10 | $0.0499 | $0.0002 | **$0.0501** |
| 1,000 videos | 1,000 | $4.99 | $0.0002 | **$4.9902** |
| 10,000 videos | 10,000 | $49.90 | $0.0002 | **$49.9002** |

A mixed list: 100 links, of which 88 have a transcript, 9 have no captions but their details arrived, and 3 are deleted or private: 97 rows charged, 97 × $0.00499 = $0.48, plus $0.0002. When the run ends, its last message gives the totals, in this form: "Done. 97 videos delivered with their data (88 of them with a transcript), 3 not found or not reachable (not charged)."

Apify's free plan gives $5 of credit every month, with no card. At this price that is about 1,000 videos a month. Unused credit does not carry over.

#### Cap your spending

Before you click **Start**, open **Run options** and type an amount into **Maximum cost per run**. The Actor stops when it reaches the amount, never charges past it, and its last message says how many videos were not processed. You see what a run cost on the run's page and under **Billing**.

### Errors and troubleshooting

#### What each status means

The run itself always ends as Succeeded with one row per entry, so a problem with one video never stops the others. `status` is about the transcript; the last column is the rule of thumb, and the `charged` field of the row has the final word.

| `status` | What it means | What to do | Charged? |
| --- | --- | --- | --- |
| `success` | The transcript was delivered. | Nothing. | Yes. |
| `no_captions` | The video has no captions, neither written nor automatic. Common for music and videos without speech. Also a live stream that is still running. | Nothing can be read. For a stream, run it again some hours after it ends. | Yes if the details arrived. |
| `language_unavailable` | There are captions, but not in the languages or caption type you chose, and the fallback is off. | Look at `availableLanguages`, then change **🌐 Transcript language**, turn the fallback on, or use **🔁 Translate to**. | Yes if the details arrived. |
| `video_unavailable` | The video was deleted or never existed. | Check the link. | No. |
| `video_unplayable` | Private, paid, blocked in the region or removed by YouTube. `message` has YouTube's reason. | Nothing can be read without an account. | No for private videos. Otherwise only if the details arrived. |
| `age_restricted` | YouTube shows it only to signed-in adults. | No transcript is possible. | Only if the details arrived. |
| `blocked` | YouTube refused every connection that was tried. | Run it again later. | No, unless the details arrived. |
| `error` | Something unexpected. `message` says what. In rare cases the transcript could not be read although the video's page answered: then the details are in the row. | Run it again. | No, unless the details arrived. |
| `invalid_input` | The entry is not a YouTube link or ID. | Copy the link again from the browser's address bar. | No. |
| `source_problem` | A channel, playlist or search could not be listed. `message` says why, for example a mistyped @handle or a private playlist. | Fix the link and run it again. | No. |

The list of possible values of `status` also contains `unsupported_url`. It belongs to the transcript tools that take video links only; here channel and playlist links are read.

#### Problems and solutions

- **"I was charged for a video without a transcript."** Its details (numbers, channel facts, comments) were delivered. Turn **📊 Video and channel details** off if you only want transcript rows.
- **"A field is empty."** `null` means YouTube has no such value for this video (no chapters, hidden likes, no music credit), or a part of the details did not arrive: check `detailsMissing`.
- **"The comment count looks rounded."** Request at least one comment (`maxComments` 1 or more) to get the exact figure.
- **"My Excel file has thousands of columns."** Omit `segments` and `comments` in the export window, and export the **Comments** view separately.
- **"Fewer results than I asked for."** A channel may have fewer public videos, a filter may have removed some, a search may return fewer results, duplicates are fetched once, the memory left out videos delivered earlier, or the spending cap or the timeout was reached. The run's last message says which.
- **"n8n gives me facts about the run."** Use **Run an Actor and Get Dataset**, set **Memory** to 4096, and raise **Limit** in **Get Items**.
- **"Zapier cut the run off."** Its synchronous runs stop after 30 seconds. Use two Zaps.

#### Limits to know

- It does not listen to the audio. A video with no captions at all has no transcript here (`no_captions`), though its numbers and comments are still delivered.
- No transcript for age-restricted, private and members-only videos.
- No dislikes. YouTube does not show them.
- No exact subscriber counts. YouTube rounds them ("27.9M").
- No exact like counts for comments above 999. YouTube shows "1.2K"; both `likes` and `likesText` are returned.
- At most 100 comments per video, and the top ones only. Replies are counted (`replyCount`) but not fetched.
- At most 5,000 videos per channel or playlist and 500 per search.
- The date filter for channels is approximate.
- Views, likes and comment counts are a snapshot of the moment of the run.

### FAQ

#### Why did a YouTube video come back without a transcript?

The `status` and `message` of its row say why. The usual reason is `no_captions`: nobody wrote captions and YouTube made no automatic ones.

#### Am I charged when there is no transcript?

Yes, if the row still carries the details of the video, because that is data you asked for. No, if the video does not exist, is private or could not be reached. The `charged` field of each row tells you.

#### What does "per 1,000" mean, and what will my run cost?

'Per 1,000' is only the unit the price is shown in; you do not buy a pack. On the Free plan each charged row costs $0.00499 at the time of writing, so 200 videos cost about $1 and 1,000 cost $4.99, plus $0.0002 per run. Paid plans pay less, down to $2.49 per 1,000.

#### Does it work with YouTube Shorts?

Yes. Paste the Shorts link, or take them from a channel. `isShort` marks them. Search results do not include Shorts.

#### And live streams?

A finished stream is read like any video, once YouTube has processed its captions. A stream that is still on air has no transcript yet (`no_captions`), but the row shows `isLiveNow` and `liveViewers`.

#### Can I give it a YouTube channel or a playlist?

Yes. Paste the channel link, a plain `@name` or the playlist link into the first box and set **🔢 Videos per channel or playlist**.

#### Which language do I get, and can it translate?

By default, the language spoken in the video. You can pick languages in order of preference, and **🔁 Translate to** asks for YouTube's own machine translation when the video offers it.

#### Does it transcribe the audio when there are no captions?

No. It reads the captions YouTube has. Without captions there is no transcript.

#### Will YouTube block it? Do I need a proxy or a YouTube API key?

You need neither, and there is nothing to configure. Connections are handled for you and are included in the price.

#### My run shows no data. Where are my results?

Open the run and its **Output** tab. If the table is empty, read the run's status message and the **Log** tab. An empty input produces one row that says so. Older results are under the left menu **Storage**, in the **Datasets** tab.

#### Why is a field empty or missing?

`null` means YouTube has no such value for this video, or a part of the details did not arrive: check `detailsMissing`. Transcript fields appear only for the formats you selected. Detail fields are absent when **📊 Video and channel details** is off.

#### Which numbers are exact?

Views, likes, duration, reply counts and the publish date are exact. The comment count is exact when you request at least one comment. Subscribers, and comment likes above 999, are rounded by YouTube.

#### How many YouTube comments can I get? Are replies included?

Up to 100 top comments per video. Replies are not fetched; `replyCount` says how many each comment has.

#### How does the date filter work, and how exact is it?

**📅 Only videos newer than** works on the rough ages in YouTube's lists. Nothing newer is left out, and a few slightly older videos can slip in. Filter on `publishedAt` afterwards for an exact cut.

#### How do I get only new videos every week?

Turn on **Only new videos since the last run**, run once, save the form as a task and schedule it. Steps in [Run it on a schedule](#run-it-on-a-schedule-and-get-only-new-videos).

#### Why did I get fewer results than I asked for?

A channel may have fewer public videos than your number, a filter may have removed some, a search may return fewer results, duplicates are fetched once, the memory left out videos delivered earlier, or the spending cap or the timeout was reached. The run's last message says which.

#### Can I get only the numbers and the comments, without the transcript?

There is no switch to skip the transcript. Select the `text` format only, and leave `text` out when you export. The price is the same.

#### I only need the transcript. Is this the right tool?

It works, but you would pay for data you do not use. The transcript tools in [Related YouTube tools](#related-youtube-tools) cost less.

#### How do I get the results into n8n, Make, Zapier or Google Sheets?

Follow the steps in [Integrations](#integrations-n8n-make-zapier-python-javascript-and-langchain). For spreadsheets, export the **Video details** and **Comments** views.

#### Can ChatGPT or Claude use it?

Yes, through MCP. Add `https://mcp.apify.com?tools=nokia2k/youtube-all-in-one-scraper` as a connector and ask in plain words.

#### What do the timestamps mean, and what is the difference between SRT and VTT?

`start` and `end` are seconds from the beginning of the video. SRT and VTT are the two common subtitle file types: SRT for video editors, VTT for web players.

#### How many videos per run, and how many runs at once?

A run takes any number of entries, with up to 5,000 videos per channel or playlist and 500 per search. How many runs you can have at the same time depends on your Apify plan, for example 32 on Starter, 128 on Scale and 256 on Business.

#### What happens if I stop a run?

Rows already delivered stay in the dataset. Videos that were not processed are not charged.

#### Is it legal to scrape YouTube video data? What about private videos?

The Actor reads only what YouTube shows publicly to any visitor. It cannot open private videos, and dislikes are not available. What you do with the texts and comments is your responsibility: respect copyright and YouTube's terms.

#### What do Actor, run, dataset and view mean?

| Word | Meaning |
| --- | --- |
| Actor | A tool that runs on Apify. This page describes one. |
| Apify Console | The web panel where you start Actors and see results. |
| Input | What you give the Actor: the form, or the same thing as JSON. |
| Run | One execution of the Actor with one input. |
| Dataset | The table where the results of a run are stored. |
| Row (item) | One line of the dataset. Here: one video. |
| View | A ready-made selection of columns of the dataset. |
| Key-value store | The place where a run keeps files, such as subtitle files and `ALL_TRANSCRIPTS.md`. |
| API, API token | A way for programs to use Apify without the website, and your secret key for it. |
| JSON, CSV | A text format for data that programs read; a plain table file that every spreadsheet opens. |
| Pay per event | You pay for each result, here each charged row. |
| Captions, transcript | The text YouTube can show under a video while it plays; the same text as a whole. |
| Auto-generated captions | Captions made by YouTube's speech recognition. Many have no punctuation. |
| Chapter | A named part of a video with a start time. |
| Most replayed | The moments of a video that viewers watch again most often. |
| Handle | A channel's short name that starts with @. |
| MCP | The standard that lets AI assistants use tools such as this one. |

#### Something went wrong. Where do I get help?

Open the **Issues** tab of this Actor. See [Support and updates](#support-and-updates).

### Related YouTube tools

Only need transcripts? The same developer makes two lighter YouTube Actors for that. Prices per 1,000 results on the Free plan at the time of writing; paid Apify plans pay less.

| Actor | Use it when you have | You get | Price |
| --- | --- | --- | --- |
| [YouTube Video to Text 📝](https://apify.com/nokia2k/youtube-video-to-text) | A big list of video links, a playlist or a channel | Plain text only, the lowest price | $1.99 |
| [YouTube Transcript Scraper ⚡](https://apify.com/nokia2k/youtube-transcript-scraper) | Video links, and someone is waiting | Text, timestamps, SRT, VTT, translation, in about 3 s | $2.99 |
| **YouTube Scraper 🧰 (you are here)** | Links, a channel, a playlist or a topic, and you need numbers | Transcript plus likes, comments, chapters, channel facts | $4.99 |

### Support and updates

Something does not work as this manual says, or you need a field that is missing? Open an issue on the **Issues** tab of this Actor. Include the link to the run and the link to the video, channel or search that gave the problem. With those two links the case can be reproduced.

Last updated: October 2026.

**Get your first video report: paste one link and click Start.**

### 🇪🇸 Guía completa en español

**Datos de videos de YouTube, una fila por video, con todo lo que YouTube muestra de él: la transcripción completa, las visualizaciones, los «me gusta» y la fecha de publicación exactos, el número de comentarios y los comentarios principales, los capítulos, los momentos más repetidos, los hashtags y los datos del canal, para videos, canales, listas de reproducción o búsquedas.**

**$4.99 por cada 1000 videos con el plan Free de Apify, y desde $2.49 con los planes de pago** (precios en el momento de escribir esto): medio centavo o menos cada uno.

**Los videos que no existen, son privados o no se pudieron alcanzar nunca se cobran, y el campo `charged` de cada fila muestra lo que se facturó.**

Este scraper de YouTube es un Actor (así llama Apify a una herramienta lista para usar que funciona en la nube) pensado para analistas, agencias, investigadores y creadores que estudian qué funciona y no quieren una herramienta para transcripciones, otra para estadísticas y una tercera para comentarios. Pega enlaces de videos, canales o listas, o escribe una búsqueda, y haz clic en **Start** («Iniciar»). Pagas por cada video que vuelve con datos: un video sin subtítulos trae igualmente sus cifras, capítulos y comentarios, así que se cobra salvo que desactives los datos. No hay nada que configurar: ni clave de API de YouTube, ni inicio de sesión, ni proxy.

Las pantallas de Apify están en inglés. Por eso los botones y pestañas aparecen aquí en inglés y en negrita, con su significado entre comillas angulares la primera vez. Los nombres de los campos, los valores de `status` y el JSON también se quedan en inglés.

#### Por qué lo eligen

- **Transcripción, estadísticas y comentarios en la misma fila,** ya emparejados. Sin unir tres hojas de cálculo a mano.
- **Todo lo que muestra YouTube:** fecha exacta de publicación, «me gusta», número de comentarios, categoría, hashtags, enlaces de la descripción, capítulos, momentos más repetidos (cuando el video ya tiene suficientes visualizaciones), créditos musicales, el resumen de IA de YouTube cuando existe, países bloqueados, videos relacionados, y el handle, los suscriptores y la insignia de verificación del canal.
- **Comentarios principales con su contexto:** hasta 100 por video, con autor, «me gusta», número de respuestas, fijado y con corazón. La vista **Comments** («Comentarios») los convierte en una tabla propia.
- **Cifras honestas.** Cada número indica si es exacto o redondeado por YouTube, y los redondeados vienen con el texto que imprimió YouTube. `detailsMissing` dice cuándo no llegó una parte; los huecos nunca se rellenan con suposiciones.
- **Videos, canales, listas y búsquedas en un mismo formulario,** con **Only new videos since the last run** («Solo videos nuevos desde la última ejecución») para vigilancia programada.
- **Una factura clara.** Cada fila dice `charged: true` o `charged: false`, y el último mensaje de la ejecución da el total.

#### Velocidad y fiabilidad medidas

- **Velocidad.** Medido en la plataforma de Apify el 7 y 8 de octubre de 2026, como tiempo total de la ejecución de principio a fin: **5 videos con todos los datos y 5 comentarios cada uno tardaron 4.6 segundos.** La transcripción, los datos y los comentarios de un video se piden a la vez, y se trabaja con 40 videos a la vez. Tus tiempos variarán un poco según YouTube y los videos.
- **Fiabilidad de la parte de transcripción.** En una prueba del 8 de octubre de 2026, 3629 videos de 20 canales en dos ejecuciones dieron 3447 transcripciones, 171 videos sin subtítulos, 10 videos con restricción de edad y 1 video fallido por tiempo agotado (0.03 %). YouTube no bloqueó ninguno. Un conjunto de 25 videos difíciles (sin subtítulos, en directo, con restricción de edad, privados, borrados, de pago, bloqueados en Estados Unidos, un video de 5 horas, en japonés, coreano y español, Shorts) recibió en todos los casos la respuesta correcta.
- **Una ejecución no se rompe.** Termina como **Succeeded** («completada») con una fila por entrada que dice qué pasó. Un problema inesperado se convierte en una fila con `status: "error"` en lugar de una ejecución fallida, así que una automatización sigue adelante.
- **Tiempos máximos.** Cada video tiene 30 segundos en total y cada petición 25 segundos. Una ejecución con **Timeout** («Tiempo máximo») deja de tomar videos nuevos poco antes del límite, termina con normalidad y dice cuántos videos no se procesaron. Esos no se cobran.
- **Antes de rendirse,** se prueban dos identidades de aplicación distintas y tres tipos de conexión (direcciones domésticas, direcciones de centros de datos y la dirección del propio servidor) antes de dar un video por `blocked` o `error`. Si Apify traslada la ejecución a otro servidor, continúa donde se quedó y nunca cobra un video dos veces.

### Inicio rápido: extrae datos de videos de YouTube en 5 pasos

Apify es la web que ejecuta esta herramienta. Necesitas una cuenta gratuita de Apify y unos cinco minutos.

1. **Crea una cuenta gratuita.** Abre `https://console.apify.com/sign-up`. Escribe tu correo y una contraseña de 8 caracteres o más y haz clic en **Sign up** («Registrarse»), o haz clic en **Continue with Google** («Continuar con Google»). Con correo, recibes un mensaje con un enlace: haz clic en él.
   - *Verás:* Apify Console («Consola de Apify»), el panel web de tu cuenta. El plan gratuito te da $5 de crédito cada mes y no pide tarjeta.
2. **Abre este Actor.** Entra en `https://apify.com/nokia2k/youtube-all-in-one-scraper` y haz clic en **Try for free** («Probar gratis»). Inicia sesión si te lo pide. Si no ves un formulario, usa el menú de la izquierda **Apify Store** («tienda de Apify»), busca `nokia2k youtube-all-in-one-scraper` y haz clic en él.
   - *Verás:* la pestaña **Input** («Entrada»). La primera casilla, **📺 Videos, channels or playlists** («Videos, canales o listas»), ya trae un video de ejemplo. El formulario viene preparado para añadir 5 comentarios principales a la fila.
3. **Pega tus enlaces** en lugar del ejemplo, uno por línea: videos, canales o listas. No cambies nada más por ahora.
4. **Haz clic en Start.**
   - *Verás:* empieza la **ejecución** (cada vez que el Actor trabaja). Unos segundos después su estado dice **Succeeded**.
5. **Abre la pestaña Output** («Salida»), **haz clic en Export** («Exportar»), **elige un formato y haz clic en Download** («Descargar»). Excel, CSV, JSON y más; **Preview** («Vista previa») te enseña el resultado antes.
   - *Verás:* primero una tabla con una fila por video: miniatura, título, estado, idioma, transcripción, canal, visualizaciones, fecha de publicación, «me gusta», comentarios y suscriptores. Esta tabla es el **dataset** («conjunto de resultados»). Después de **Download**, el archivo está donde tu navegador guarda las descargas.

La entrada más pequeña, en JSON (la pestaña **Input** tiene un selector entre el formulario y JSON):

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

Dos cosas que conviene saber antes de tu primer archivo Excel o CSV:

- Una celda de hoja de cálculo no puede contener una lista, así que las listas como `segments` (las líneas de subtítulos) y `comments` se reparten en muchas columnas, y estos formatos se detienen en 2000 columnas. En la ventana de exportación, escribe `segments` y `comments` en **Omit fields** («Excluir campos»). La transcripción sigue ahí como `text`, y los comentarios tienen su propia tabla (mira «Exporta los comentarios como tabla propia»).
- Para encontrar tus resultados más tarde, usa el menú de la izquierda **Runs** («Ejecuciones»), o **Storage** («Almacenamiento») y después la pestaña **Datasets**. En el plan gratuito, los resultados sin nombre se borran a los 7 días. Para conservarlos, abre el dataset, abre el menú **Actions** («Acciones») y haz clic en **Rename** («Cambiar nombre»).

### Qué datos recibes de cada video

Los resultados de una ejecución se guardan en un **dataset**, una tabla que se queda en Apify. Cada video es una fila. Una fila tiene hasta 74 campos, agrupados abajo. Un campo muestra `null` (vacío) cuando YouTube no tiene ese valor para el video, y una lista vacía `[]` cuando la página se leyó y no hay nada que enumerar.

Las palabras «exacto» y «redondeado» se usan con rigor. **Exacto** significa que YouTube dio la cifra completa. **Redondeado** significa que YouTube solo publica una abreviatura como "27.9M", así que el número de la fila es 27 900 000 y el texto que imprimió YouTube se guarda en un segundo campo.

#### Video

| Campo | Qué significa | Ejemplo |
| --- | --- | --- |
| `videoId`, `url` | El identificador de 11 caracteres y el enlace estándar. | `arj7oStGLkU` |
| `title`, `description` | El título y el texto bajo el video. | `Inside the Mind of a Master Procrastinator \| Tim Urban \| TED` |
| `keywords`, `hashtags` | Etiquetas de quien lo subió; hashtags que aparecen sobre el título y en la descripción, cada uno una vez. | `["#TED"]` |
| `descriptionLinks` | Todos los enlaces de la descripción, como `text` y `url`, sin la redirección de YouTube. Se omiten los enlaces que solo saltan a otro momento del mismo video. | `[{"text": "ted.com", "url": "https://www.ted.com"}]` |
| `thumbnailUrl` | Enlace a la imagen de vista previa más grande que devuelve YouTube. | |
| `category` | Categoría de YouTube. | `People & Blogs` |
| `publishedAt` | Fecha y hora exactas de publicación, en UTC (ISO 8601 terminado en `Z`). Si YouTube solo da el día, el valor es solo la fecha. | `2016-04-06T16:59:35Z` |
| `uploadedAt` | Fecha y hora exactas en que se subió el archivo, en UTC. Puede ser anterior a la de publicación. | |
| `publishedDateText` | La fecha tal como YouTube la imprime bajo el video. | `Apr 6, 2016` |
| `isShort`, `isLive`, `isLiveNow` | Un Short; un directo o su grabación; un directo en emisión ahora. | `false` |
| `liveStartedAt`, `liveEndedAt` | En directos y sus grabaciones: cuándo empezó y terminó la emisión. | `null` |
| `isUnlisted`, `isFamilySafe`, `isMembersOnly`, `isPaid` | Marcas de YouTube: accesible solo con el enlace; apto para familias; para miembros del canal; ligado a una compra, un alquiler o una suscripción de miembro. | `false` |
| `blockedCountries`, `availableCountries` | Códigos de los países donde el video está bloqueado (`[]`: se puede ver en todas partes); donde se puede ver (solo cuando esa lista es más corta). | `[]` |
| `music`, `musicTracks` | Canción, artista y álbum cuando YouTube acredita música; todas las pistas acreditadas cuando hay varias. | `null` |
| `aiSummary` | El resumen escrito por IA que YouTube muestra bajo algunos videos. Solo cuando YouTube lo muestra para el video, lo que es poco frecuente; `null` en los demás casos. | `null` |
| `relatedVideos` | Hasta 10 videos que YouTube sugiere a continuación, cada uno con su identificador y título. | 10 elementos |

#### Cifras

| Campo | Qué significa | Exacto o redondeado | Ejemplo |
| --- | --- | --- | --- |
| `durationSeconds` | Duración del video en segundos. | Exacto. | `844` |
| `viewCount` | Visualizaciones en el momento de la ejecución. | Exacto. | `62013820` |
| `likeCount` | «Me gusta». `null` cuando el propietario los oculta. | Exacto. | `2054977` |
| `commentCount` | Número de comentarios. | Exacto cuando `maxComments` es 1 o más. Con `maxComments` en 0 es la cifra redondeada de YouTube ("79K" pasa a 79000). | `79650` |
| `commentCountText` | El número de comentarios tal como lo imprime YouTube. | Texto, tal cual. | `79,650 Comments` |
| `liveViewers` | Personas viendo un directo en emisión. | Tal como se muestra en ese momento. | `null` |

Otras dos cifras están en otros grupos: `channelSubscribers` siempre está redondeado, y los `likes` de un comentario son exactos por debajo de 1000 y redondeados por encima. Los «no me gusta» no están disponibles: YouTube ya no los muestra.

#### Canal

| Campo | Qué significa | Ejemplo |
| --- | --- | --- |
| `channelName`, `channelId` | Nombre e identificador de YouTube del canal. | `TED`, `UCAuUUnT6oDeKwE6v1NGQxug` |
| `channelHandle`, `channelUrl` | El @handle y el enlace del canal. | `@TED` |
| `channelSubscribers` | Suscriptores. **Redondeados por YouTube a tres cifras**: "27.9M" pasa a 27900000. La cifra exacta no es pública. | `27900000` |
| `channelSubscribersText` | Los suscriptores tal como los imprime YouTube. | `27.9M subscribers` |
| `channelVerified` | `true` cuando el canal tiene insignia de verificación. | `true` |
| `channelAvatar` | Enlace a la foto de perfil del canal. | un enlace |

#### Capítulos y momentos más repetidos

| Campo | Qué significa | Ejemplo |
| --- | --- | --- |
| `chapters` | Los capítulos del video: `title`, `start` en segundos enteros y `startText` tal como lo muestra YouTube. Se usan los capítulos del creador; si no hay, los que generó YouTube. `[]` cuando el video no tiene capítulos. | `[{"title": "The life calendar", "start": 756, "startText": "12:36"}]` |
| `chaptersAreAuto` | `true` cuando YouTube creó los capítulos, `false` cuando los escribió el creador. | `true` |
| `mostReplayed` | Los momentos que más vuelven a ver los espectadores, de mayor a menor, como mucho cinco. Cada uno tiene `start` y `end` en segundos, `intensity` y `labeled` (`true` cuando YouTube marca el momento como "Most replayed"). **`intensity` es una puntuación relativa de 0 a 1, no un recuento**: 1 es la parte más repetida de este video. Solo se rellena cuando YouTube muestra el gráfico "Most replayed" del video, lo que hace cuando suficientes personas lo han visto: los videos con pocas visualizaciones, muchos videos de solo unos días, los muy largos y los directos no tienen estos datos (`null`). | `[{"start": 481.08, "end": 489.52, "intensity": 1}]` |

#### Comentarios

| Campo | Qué significa | Ejemplo |
| --- | --- | --- |
| `comments` | Los comentarios principales, en el orden en que los muestra YouTube, hasta `maxComments`. `null` cuando no se pidieron comentarios. | mira el ejemplo |
| `commentsDisabled` | `true` cuando el autor desactivó los comentarios, `false` cuando la sección está, `null` cuando la página no lo dice (por ejemplo, un directo en emisión). | `false` |

Cada comentario tiene estas partes:

| Parte | Qué significa | Exacto o redondeado |
| --- | --- | --- |
| `id` | Identificador del comentario en YouTube. | |
| `text` | El comentario. | |
| `author` | El @handle del autor. | |
| `likes` | «Me gusta» del comentario. | **Exactos por debajo de 1000. Por encima, YouTube solo muestra "3.2K", que pasa a 3200.** |
| `likesText` | Los «me gusta» tal como los imprime YouTube. | Texto, tal cual (`3.2K`). |
| `replyCount` | Número de respuestas. | Exacto. |
| `publishedText` | Antigüedad del comentario tal como se muestra. | Aproximada (`7 years ago`). |
| `isPinned`, `isHearted` | `true` cuando el creador lo fijó, o le dio un corazón. | |
| `authorIsChannelOwner` | `true` cuando lo escribió el creador. | |

#### Transcripción

| Campo | Qué significa | Ejemplo |
| --- | --- | --- |
| `language`, `languageName` | Código y nombre del idioma que recibiste. | `en`, `English` |
| `isAutoGenerated` | `true` cuando los subtítulos vienen del reconocimiento de voz de YouTube, `false` cuando los escribió una persona. | `false` |
| `isTranslated`, `translatedFrom` | Si es la traducción automática de YouTube, y desde qué idioma. | `false`, `null` |
| `availableLanguages` | Todos los idiomas de subtítulos del video: `code`, `name`, `isAutoGenerated`, `isTranslatable`. | |
| `segmentCount`, `wordCount`, `charCount` | Líneas de subtítulos (o bloques), palabras y caracteres. Contados con exactitud. | `315`, `2277`, `12671` |
| `text` | Toda la transcripción como un párrafo. Con el formato `text`. | `So in college, I was a government major…` |
| `timestampedText` | Una línea por subtítulo: `[MM:SS] texto`. | `[00:01] All right, so here we are…` |
| `segments` | Líneas de subtítulos con `start`, `duration` y `end` en segundos y su `text`. | |
| `srt`, `vtt` | El contenido de un archivo de subtítulos `.srt` o `.vtt`. | |
| `markdown` | La transcripción como documento Markdown con título, canal, fecha y enlace. | |
| `files` | Enlaces de descarga de los archivos guardados, por formato. Con `saveFiles` activado. | |
| `data` | Líneas de subtítulos como cadenas `start`, `dur` y `text`. Solo cuando la entrada usó el campo único `videoUrl`. | |

#### Origen y control

| Campo | Qué significa | Ejemplo |
| --- | --- | --- |
| `source`, `sourceType`, `sourceTitle` | El canal, la lista o la búsqueda de donde vino un video: enlace o palabras de búsqueda, `channel`/`playlist`/`search`, y su nombre. | `https://www.youtube.com/@TED`, `channel`, `TED` |
| `positionInSource` | Posición del video en esa lista, empezando en 1. Exacta. | `1` |
| `publishedText` | La antigüedad del video tal como la muestra la lista de YouTube. Aproximada: usa `publishedAt` para la fecha exacta. | `2 hours ago` |
| `input` | El valor de tu entrada que produjo esta fila. Las filas llegan en el orden en que terminan. | `https://www.youtube.com/watch?v=arj7oStGLkU` |
| `status` | Qué pasó con la **transcripción** de este video. | `success` |
| `message` | Una explicación sencilla cuando el estado no es `success`, o una nota, por ejemplo sobre un cambio de idioma. | (vacío) |
| `charged` | `true` cuando esta fila se facturó. | `true` |
| `detailsMissing` | Partes de los datos que YouTube no respondió esta vez. `[]` cuando llegó todo. | `[]` |
| `scrapedAt` | Cuándo se produjo la fila, en UTC. | `2026-10-08T09:00:00+00:00` |

#### Ejemplo de salida: una fila correcta y una fila no_captions

El video de ejemplo del formulario, pedido con el formato `text` y un comentario. Acortado: los textos largos terminan en "…" y se omiten algunos campos. Valores leídos el 8 de octubre de 2026.

```json
{
    "videoId": "arj7oStGLkU",
    "url": "https://www.youtube.com/watch?v=arj7oStGLkU",
    "status": "success",
    "message": "",
    "charged": true,
    "detailsMissing": [],
    "title": "Inside the Mind of a Master Procrastinator | Tim Urban | TED",
    "category": "People & Blogs",
    "publishedAt": "2016-04-06T16:59:35Z",
    "isShort": false,
    "isLive": false,
    "durationSeconds": 844,
    "viewCount": 62013820,
    "likeCount": 2054977,
    "commentCount": 79650,
    "commentsDisabled": false,
    "channelName": "TED",
    "channelId": "UCAuUUnT6oDeKwE6v1NGQxug",
    "channelHandle": "@TED",
    "channelUrl": "https://www.youtube.com/@TED",
    "channelSubscribers": 27900000,
    "channelSubscribersText": "27.9M subscribers",
    "channelVerified": true,
    "chapters": [
        { "title": "My procrastination journey", "start": 0, "startText": "0:00" },
        { "title": "The procrastinator's brain", "start": 176, "startText": "2:56" },
        { "title": "The monkey and the playground", "start": 249, "startText": "4:09" },
        { "title": "The role of the panic monster", "start": 436, "startText": "7:16" },
        { "title": "Two types of procrastination", "start": 599, "startText": "9:59" },
        { "title": "The life calendar", "start": 756, "startText": "12:36" }
    ],
    "chaptersAreAuto": true,
    "mostReplayed": [
        { "start": 481.08, "end": 489.52, "intensity": 1 },
        { "start": 16.88, "end": 25.32, "intensity": 0.951 }
    ],
    "comments": [
        {
            "text": "He procrastinated in creating a Ted talk about procrastination. Ted definitely picked the right man for the job.",
            "author": "@SWIFTzTrigger",
            "likes": 3200,
            "likesText": "3.2K",
            "replyCount": 2,
            "publishedText": "7 years ago"
        }
    ],
    "language": "en",
    "languageName": "English",
    "isAutoGenerated": false,
    "isTranslated": false,
    "translatedFrom": null,
    "segmentCount": 315,
    "wordCount": 2277,
    "charCount": 12671,
    "text": "So in college, I was a government major, which means I had to write a lot of papers. …",
    "input": "https://www.youtube.com/watch?v=arj7oStGLkU",
    "scrapedAt": "2026-10-08T09:00:00+00:00"
}
```

Léelo como comprobación de las reglas de arriba: `likeCount` y `viewCount` son exactos, `commentCount` es exacto porque se pidió un comentario, `channelSubscribers` está redondeado, y los `likes` del comentario están redondeados porque pasan de 999.

Un video sin subtítulos en la misma ejecución. El identificador y el título son marcadores, y los campos de datos (fecha, «me gusta», comentarios, capítulos y demás) se rellenan como en cualquier video y aquí se omiten. Como sus datos llegaron, la fila se cobra:

```json
{
    "videoId": "<11-character ID>",
    "url": "https://www.youtube.com/watch?v=<11-character ID>",
    "status": "no_captions",
    "message": "The video has no captions, neither uploaded nor auto-generated.",
    "title": "<title of the video>",
    "language": null,
    "availableLanguages": [],
    "wordCount": 0,
    "detailsMissing": [],
    "charged": true
}
```

Con **📊 Video and channel details** («Datos del video y del canal») desactivado, la misma fila no traería datos y diría `charged: false`.

#### Cinco vistas de los mismos datos

Una **vista** es una selección de columnas ya preparada. En la pestaña **Output** puedes elegir entre las vistas de este Actor. Muestran las mismas filas de formas distintas y no cuestan nada.

| Vista | Qué muestra |
| --- | --- |
| **Overview** («Resumen») | Miniatura, título, estado, idioma, automático, duración, palabras, transcripción, canal, visualizaciones, encontrado en, publicado, «me gusta», comentarios, suscriptores, enlace del video, mensaje. |
| **Subtitle files** («Archivos de subtítulos») | Identificador del video, título, idioma, SRT, WebVTT. |
| **Languages** («Idiomas») | Identificador del video, título, estado, idioma devuelto, nombre del idioma, automático, traducido, idiomas disponibles. |
| **Video details** («Datos del video») | La tabla de estadísticas, sin la transcripción en medio: título, nombre del canal, handle del canal, suscriptores, publicado el, visualizaciones, «me gusta», comentarios, categoría, duración (segundos), Short, hashtags, enlace del video. |
| **Comments** («Comentarios») | Un comentario por fila: identificador del video, título del video, autor, comentario, «me gusta», respuestas, cuándo. |

**Video details** es la tabla que un analista suele querer primero: una línea por video, solo cifras.

#### Exporta los comentarios como tabla propia

1. Abre la ejecución y su pestaña **Output**.
2. Elige la vista **Comments**. La tabla muestra ahora un comentario por fila, con el identificador y el título del video repetidos en cada línea.
3. Haz clic en **Export**, elige Excel o CSV y haz clic en **Download**. Si la ventana de exportación te deja elegir una vista, deja **Comments**.

También puedes descargar la misma tabla con un enlace directo. Abre la pestaña **Storage** de la ejecución, mira **Dataset** y copia el identificador del dataset. Después abre esta dirección en tu navegador, con tu identificador en lugar de `<DATASET_ID>`:

```text
https://api.apify.com/v2/datasets/<DATASET_ID>/items?view=comments&format=xlsx&clean=true
```

Usa `format=csv` para un archivo CSV. Si la dirección responde que no tienes acceso, añade `&token=<YOUR_APIFY_TOKEN>` al final. Las dos tablas llevan `videoId`: es la clave que une un comentario con su video en una hoja de cálculo o una base de datos.

#### Cuando falta una parte de los datos

Los datos de un video se leen en hasta tres partes, a la vez que la transcripción. Si una parte no responde, las otras se entregan igualmente, y `detailsMissing` nombra la parte que falta. El Actor nunca rellena un hueco con una suposición: los campos de una parte que falta son `null`.

| Valor en `detailsMissing` | Qué no llegó | Campos vacíos por ello |
| --- | --- | --- |
| `microformat` | La ficha de datos de la página. | `uploadedAt`, `category`, `isShort`, `isUnlisted`, `isFamilySafe`, `isPaid`, las listas de países, las horas de inicio y fin del directo. `publishedAt` lleva entonces solo el día, tomado de la fecha impresa bajo el video cuando se puede leer. Las visualizaciones y los «me gusta» siguen siendo exactos: se leen de la otra parte. |
| `watch` | La página de reproducción. | `hashtags`, `descriptionLinks`, `chapters`, `mostReplayed`, `music`, `aiSummary`, `relatedVideos`, `publishedDateText`, `isMembersOnly`, `commentsDisabled`, `channelSubscribers`, `channelVerified`, `channelAvatar`. |
| `comments` | La lista de comentarios, o sus páginas siguientes. | `comments` es `null`, o más corta de lo que pediste. |

Qué hacer: vuelve a ejecutar ese video. Una segunda ejecución es un segundo cobro si entrega datos. Una fila con una parte que falta se cobra igualmente si llegó el resto, así que mira `detailsMissing` antes de fiarte de un campo vacío. En un video privado o borrado la lista es `[]`: no falta nada, simplemente no hay nada que leer, y la fila es gratis.

### Casos de uso

- **Descubre por qué ganan algunos videos:** compara lado a lado visualizaciones, «me gusta», comentarios, capítulos y momentos más repetidos de los videos de un canal.
- **Lee al público, no solo el video:** exporta los comentarios principales de cada video como tabla propia para analizar opiniones y preguntas.
- **Audita el canal de un competidor** en una ejecución: lo que dice (transcripción), cómo rinde (cifras) y cómo reacciona la gente (comentarios).
- **Sigue un tema cada semana:** una búsqueda programada con solo videos nuevos entrega los videos recientes con sus estadísticas y comentarios.
- **Crea un conjunto de datos para investigación o un panel** con fechas exactas, visualizaciones y «me gusta» exactos, y el redondeo de YouTube señalado donde se aplica.
- **Informa a un cliente en minutos:** convierte una lista de videos de influencers en una hoja con transcripción, alcance y reacción del público.

### Ejemplos listos para usar: ábrelo y pulsa Start

Cada ejemplo es una configuración guardada y probada, con su propia página. Ábrelo, pulsa **Run example** y tendrás una copia que funciona y que puedes cambiar.

- [Scrape a YouTube video's likes, comments and transcript](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/scrape-a-youtube-video-s-likes-comments-and-transcript)
- [Export the top 100 comments of a YouTube video](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/export-the-top-100-comments-of-a-youtube-video)
- [Track competitor YouTube channels: views, likes, topics](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/track-competitor-youtube-channels-views-likes-topics)
- [Get YouTube chapters and most replayed moments](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/get-youtube-chapters-and-most-replayed-moments)
- [Find YouTube influencers in a niche by keyword](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/find-youtube-influencers-in-a-niche-by-keyword)
- [YouTube channel stats: views, likes and comments per video](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-channel-stats-views-likes-and-comments-per-video)
- [YouTube comments for sentiment analysis](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-comments-for-sentiment-analysis)
- [YouTube Shorts scraper with views and likes](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-shorts-scraper-with-views-and-likes)
- [YouTube keyword research: top videos with stats](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-keyword-research-top-videos-with-stats)
- [YouTube video description links and hashtags scraper](https://apify.com/nokia2k/youtube-all-in-one-scraper/examples/youtube-video-description-links-and-hashtags-scraper)

### Ejemplos de entrada

#### Todos los campos de entrada

Los campos van en el orden del formulario. Necesitas al menos un enlace en la primera casilla o una línea en la casilla de búsqueda. Todo lo demás tiene un valor por defecto.

**Videos, idioma y formatos**

| Campo del formulario (nombre en JSON) | Qué es | Cuándo tocarlo | Ejemplo |
| --- | --- | --- | --- |
| **📺 Videos, channels or playlists** (`urls`) | Enlaces de YouTube, uno por línea. Un enlace de video da ese video. Un enlace de canal o un simple `@nombre` da los videos del canal, primero los más nuevos. Un enlace de lista da sus videos en su orden. Sirven enlaces de reproducción, `youtu.be`, Shorts, directos y embed, y también el identificador de 11 caracteres. Un enlace pegado dos veces se pide y se cobra una vez. | Siempre, salvo que busques en su lugar. | `https://www.youtube.com/@TED` |
| **🔢 Videos per channel or playlist** (`maxVideosPerSource`) | «Videos por canal o lista»: cuántos tomar de cada canal o lista. Por defecto 50, de 1 a 5000. El formulario viene con 5. | Empieza con poco y súbelo después. | `30` |
| **🌐 Transcript language** (`languages`) | «Idioma de la transcripción». Déjalo en **Original language** («Idioma original») y cada video llega en el idioma en que se habla. O elige idiomas por orden de preferencia: se usa el primero que tenga el video. 70 idiomas en la lista; también puedes escribir un código (`pt-BR`) o un nombre (`Spanish`, `español`, `Deutsch`). | Cuando necesitas un idioma concreto. | `["es", "en"]` |
| **📄 Output formats** (`outputFormats`) | «Formatos de salida»: `segments`, `text`, `timestampedText`, `srt`, `vtt`, `markdown`. Por defecto: `segments` y `text`. Los formatos adicionales no cuestan nada. | Elige solo lo que uses: filas más pequeñas y exportaciones más rápidas. | `["text"]` |
| **📚 Also give me everything as one Markdown file** (`combinedFile`) | «Dame también todo en un archivo Markdown»: guarda todas las transcripciones de la ejecución en `ALL_TRANSCRIPTS.md` (pestaña **Storage** de la ejecución, **Key-value store**, «almacén de archivos»). Las ejecuciones grandes se dividen en archivos de unos 8 MB. Desactivado por defecto. | Para subirlo todo de una vez a ChatGPT, Claude, NotebookLM o una base de conocimiento. | `true` |
| **💾 Also save subtitle files I can download** (`saveFiles`) | «Guardar también archivos de subtítulos que pueda descargar»: un archivo por video para cada formato de texto elegido (`.srt`, `.vtt`, `.txt`), con enlaces de descarga en `files`. Desactivado por defecto. | Cuando necesitas archivos de subtítulos de verdad. | `true` |

**Datos y comentarios**

| Campo del formulario (nombre en JSON) | Qué es | Cuándo tocarlo | Ejemplo |
| --- | --- | --- | --- |
| **📊 Video and channel details** (`includeDetails`) | Añade todo lo que va más allá de la transcripción (fecha, «me gusta», número de comentarios, capítulos, momentos más repetidos, hashtags, datos del canal y lo demás). Activado por defecto. | Desactívalo solo si quieres la transcripción sola. Desactivado, tampoco se piden comentarios, y solo se cobran las filas con transcripción. | `true` |
| **💬 Top comments per video** (`maxComments`) | «Comentarios principales por video»: cuántos añadir a cada fila, de 0 a 100. Por defecto 20; el formulario viene con 5. Las respuestas en sí no se piden. | Súbelo para estudiar al público; 0 para ninguno. Con 1 o más, `commentCount` es exacto. | `50` |

**Buscar en lugar de enlaces**

| Campo del formulario (nombre en JSON) | Qué es | Cuándo tocarlo | Ejemplo |
| --- | --- | --- | --- |
| **🔎 What to search for** (`searchQueries`) | «Qué buscar»: lo que escribirías en el buscador de YouTube, una búsqueda por línea. Para cada búsqueda recibes los videos que YouTube posiciona más alto. La búsqueda devuelve videos normales, no Shorts, canales ni listas. | Cuando tienes un tema, no enlaces. | `how to learn spanish` |
| **🔢 Videos per search** (`maxVideosPerSearch`) | Por defecto 10, hasta 500. El formulario viene con 5. | Para una muestra más amplia. | `20` |
| **📅 Uploaded** (`searchUploadDate`) | «Fecha de subida», filtro propio de YouTube: `any`, `hour`, `today`, `week`, `month`, `year`. | Para estudiar solo videos recientes. | `month` |
| **⏱️ Length** (`searchDuration`) | «Duración», filtro propio de YouTube: `any`, `short` (menos de 4 minutos), `medium` (de 4 a 20), `long` (más de 20). | Para dejar fuera clips o charlas largas. | `medium` |
| **↕️ Order** (`searchSortBy`) | «Orden»: `relevance` es el orden de YouTube. `date` y `views` ordenan así los videos encontrados; no encuentran los más nuevos ni los más vistos de todo YouTube. | Combina `date` con **📅 Uploaded**. | `views` |
| **Only videos that have captions (recommended)** (`onlyWithCaptions`) | «Solo videos con subtítulos (recomendado)»: el filtro de YouTube para subtítulos subidos por el autor. Activado por defecto, así que quedan fuera los videos con solo subtítulos automáticos. | Desactívalo para incluirlos, o para videos sin subtítulos que quieres por sus cifras y comentarios. | `false` |

**Filtros de canales y listas**

| Campo del formulario (nombre en JSON) | Qué es | Cuándo tocarlo | Ejemplo |
| --- | --- | --- | --- |
| **📅 Only videos newer than** (`newerThan`) | «Solo videos más recientes que»: una fecha, o una antigüedad como `30 days` o `6 months`. Vacío significa sin límite. Aproximado: las listas de YouTube muestran la antigüedad de forma aproximada («hace 3 semanas»), así que nunca se deja fuera nada más nuevo y unos pocos videos justo por encima del límite pueden colarse. | Para «qué ha publicado este canal últimamente». | `30 days` |
| **Only new videos since the last run** (`onlyNewVideos`) | Para ejecuciones programadas: cada ejecución entrega solo los videos que no había entregado antes para los mismos canales, listas y búsquedas. Desactivado por defecto. | Mira «Ejecútalo de forma programada y recibe solo los videos nuevos». | `true` |
| **Memory name** (`memoryName`) | «Nombre de la memoria». Opcional, solo con el campo anterior: el nombre de la lista de videos entregados. | Para mantener una sola lista aunque cambien los enlaces. | `"competitors-weekly"` |
| **🎞️ Kinds of videos to take from a channel** (`contentTypes`) | «Tipos de videos del canal»: `videos`, `shorts`, `streams`. Los tres por defecto. Se aplica a canales, no a listas. | Desmarca lo que no necesites. | `["videos"]` |

**Más opciones**

| Campo del formulario (nombre en JSON) | Qué es | Cuándo tocarlo | Ejemplo |
| --- | --- | --- | --- |
| **🔁 Translate to** (`translateTo`) | «Traducir a»: la traducción automática de YouTube, que se usa cuando el video no tiene subtítulos en ese idioma. No se ofrece para todos los videos: entonces recibes el idioma original y una nota en `message`. | Todas las transcripciones en un idioma. | `es` |
| **If my language is missing, give me the original language** (`fallbackToAnyLanguage`) | «Si falta mi idioma, dame el original». Activado por defecto. Desactivado: sin transcripción para los videos sin tus idiomas (`language_unavailable`). | Cuando otro idioma no te sirve. | `false` |
| **Caption type** (`captionType`) | «Tipo de subtítulos»: `any` (primero los de personas), `manual` (solo de personas) o `auto` (solo automáticos). | `manual` cuando importan la puntuación y los nombres. | `manual` |
| **Merge caption lines into blocks** (`mergeSegmentsSeconds`) | «Unir líneas en bloques» de unos tantos segundos, de 0 a 3600. 0 conserva las líneas originales. Es la división en fragmentos (chunking) para RAG y bases de datos vectoriales: cada bloque es un fragmento (chunk) de RAG con su hora de inicio y de fin. | Para índices de búsqueda, chunks de RAG y bases de datos vectoriales. | `30` |
| **Include video details** (`includeMetadata`) | «Incluir datos del video»: los datos básicos que acompañan a la transcripción: canal, duración, visualizaciones, descripción, etiquetas y miniatura. Activado por defecto. | Rara vez. Déjalo activado. | `true` |

#### Un video con todo y 20 comentarios

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

#### Un lote de videos

```json
{
    "urls": [
        "https://www.youtube.com/watch?v=arj7oStGLkU",
        "https://youtu.be/jNQXAC9IVRw"
    ],
    "outputFormats": ["text"],
    "maxComments": 10
}
```

#### Los 30 videos normales más nuevos de un canal, con 50 comentarios cada uno

````json
{
    "urls": ["https://www.youtube.com/@TED"],
    "maxVideosPerSource": 30,
    "conten



# Actor input Schema

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

Paste YouTube links, one per line. A <b>channel</b> link (<code>https://www.youtube.com/@name</code>) gives you the videos of the channel, newest first. A <b>playlist</b> link gives you the videos of the playlist. A <b>video</b> link gives you that one video. You can mix them freely, and a plain <code>@name</code> works too.
## `maxVideosPerSource` (type: `integer`):

How many videos to take from each channel or playlist. Start with a small number to see what you get, then raise it. You only pay for transcripts that are delivered.
## `languages` (type: `array`):

Leave it on <b>Original language</b> to get each video in the language it is spoken in: you do not need to know the language in advance. Or pick one or more languages in order of preference, and the first one the video has is used. You can also type any language code (<code>pt-BR</code>, <code>es-419</code>) or a language name (<code>Spanish</code>, <code>español</code>, <code>German</code>). Captions written by people are preferred over auto-generated ones. Every row tells you which language was returned and which other languages the video has.
## `outputFormats` (type: `array`):

Choose how each transcript is returned. You can pick several: the price per transcript stays the same.
## `combinedFile` (type: `boolean`):

Saves all transcripts of the run into one file, <code>ALL_TRANSCRIPTS.md</code>, with a heading, the channel, the date and the link for every video. Upload it to ChatGPT, Claude, NotebookLM or your knowledge base in one go. You find it in the run's <b>Storage &gt; Key-value store</b> tab. Large runs are split into files of about 8 MB. The price stays the same.
## `saveFiles` (type: `boolean`):

Saves a ready-to-use file per video for each text format you selected above: <code>.srt</code>, <code>.vtt</code> and <code>.txt</code>. Each row gets a <code>files</code> field with direct download links, and all files are listed in the run's <b>Storage &gt; Key-value store</b> tab. The price per transcript stays the same.
## `includeDetails` (type: `boolean`):

Adds everything YouTube shows about the video: exact publish date, likes, number of comments, category, hashtags, links in the description, chapters, the most replayed moments and YouTube's AI summary (both only when YouTube shows them for the video), music credits, countries where it is blocked, and the channel's name, handle, subscribers and verified badge.
## `maxComments` (type: `integer`):

How many of the top comments to add to each row, with author, likes and reply count. 0 for none.
## `searchQueries` (type: `array`):

Type what you would type into YouTube's search box, one search per line. For each search you get the transcripts of the videos YouTube ranks highest. No links needed.
## `maxVideosPerSearch` (type: `integer`):

How many of the top results to take for each search. You only pay for transcripts that are delivered.
## `searchUploadDate` (type: `string`):

Keep only videos uploaded recently. This is YouTube's own filter.
## `searchDuration` (type: `string`):

Keep only short, medium or long videos. This is YouTube's own filter.
## `searchSortBy` (type: `string`):

Relevance is what YouTube shows by default. The other two put the found videos in order of date or views.
## `onlyWithCaptions` (type: `boolean`):

Asks YouTube for videos with captions only, so nearly every result comes back with a transcript.
## `newerThan` (type: `string`):

Leave empty for no limit. Pick a date, or an age such as <code>30 days</code> or <code>6 months</code>. YouTube's lists show the age of a video only roughly ("3 weeks ago"), so the cut is approximate: nothing newer is ever left out, and a few videos just past the limit can slip in. Every row carries the exact date in <code>publishedAt</code>.
## `onlyNewVideos` (type: `boolean`):

Turn this on when you run the Actor on a <b>schedule</b> (for example every day). Each run then gives you only the videos it has not delivered before for the same channels, playlists and searches, so you never get, or pay for, the same video twice. The first run delivers everything it finds and remembers it. The list of delivered videos is kept in your own Apify account, in the key-value store named <code>youtube-transcripts-memory</code> (<b>Storage &gt; Key-value stores</b>). Videos that failed are tried again next time. Video links you paste directly are always delivered.
## `memoryName` (type: `string`):

Optional. Used only with <b>Only new videos since the last run</b>. Leave it empty and the Actor makes a name from your channels, playlists and searches, so every combination has its own list. Type a name (for example <code>my-daily-news</code>) to choose it yourself: the same name keeps adding to the same list even if you change the links, and a different name starts a separate list. Letters, digits and <code>-_.!'()</code>; other characters become <code>-</code>.
## `contentTypes` (type: `array`):

A channel can hold regular videos, Shorts and recordings of live streams. Untick what you do not need.
## `translateTo` (type: `string`):

Pick a language to get YouTube's own machine translation when the video has no captions in that language. If the video already has captions in it, those are returned instead, because they are better than a machine translation. YouTube does not offer translation for every video: when it does not, you get the original language and a note in <code>message</code>.
## `fallbackToAnyLanguage` (type: `boolean`):

When on, a video without captions in the languages you picked still returns its transcript in its original language, and the <code>language</code> and <code>message</code> fields tell you which one. Turn it off to skip those videos instead. Skipped videos are not charged.
## `captionType` (type: `string`):

Choose which captions are accepted. Auto-generated captions are produced by YouTube's speech recognition and have no punctuation in many languages.
## `mergeSegmentsSeconds` (type: `integer`):

YouTube captions come in lines of a few words. Set a number of seconds, for example 30, to join them into longer blocks. This is useful for chapters, search indexes and chunking for RAG and vector databases: each block becomes one RAG chunk with its start and end time. Use 0 to keep the original lines.
## `includeMetadata` (type: `boolean`):

Adds channel, duration, view count, description, keywords and thumbnail to every row. The video title is always included.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/@TED",
    "https://www.youtube.com/watch?v=arj7oStGLkU"
  ],
  "maxVideosPerSource": 5,
  "languages": [
    "es",
    "en"
  ],
  "outputFormats": [
    "text",
    "markdown"
  ],
  "combinedFile": false,
  "saveFiles": false,
  "includeDetails": true,
  "maxComments": 5,
  "searchQueries": [
    "how to learn spanish",
    "iphone 17 review"
  ],
  "maxVideosPerSearch": 5,
  "searchUploadDate": "any",
  "searchDuration": "any",
  "searchSortBy": "relevance",
  "onlyWithCaptions": true,
  "newerThan": "30 days",
  "onlyNewVideos": false,
  "memoryName": "my-daily-news",
  "contentTypes": [
    "videos"
  ],
  "translateTo": "es",
  "fallbackToAnyLanguage": true,
  "captionType": "any",
  "mergeSegmentsSeconds": 0,
  "includeMetadata": true
}
````

# Actor output Schema

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

All results of the run, one item per video. The 'charged' field of each item says whether it was charged.

# 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"
    ],
    "maxVideosPerSource": 5,
    "maxComments": 5,
    "maxVideosPerSearch": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("nokia2k/youtube-all-in-one-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"],
    "maxVideosPerSource": 5,
    "maxComments": 5,
    "maxVideosPerSearch": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("nokia2k/youtube-all-in-one-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"
  ],
  "maxVideosPerSource": 5,
  "maxComments": 5,
  "maxVideosPerSearch": 5
}' |
apify call nokia2k/youtube-all-in-one-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nokia2k/youtube-all-in-one-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/jjPVsmItONlmlRYZa/builds/6Dhyab50WYIjxtzIo/openapi.json
