# YouTube Video, Playlist & Channel Downloader with Metadata (`nimbryxo-studio/youtube-video-playlist-and-channel-downloader`) Actor

Download YouTube videos from direct links, playlists, channels, or search phrases at your chosen quality, with a public file link plus title, stats, description and subtitles per video.

- **URL**: https://apify.com/nimbryxo-studio/youtube-video-playlist-and-channel-downloader.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## YouTube Video, Playlist & Channel Downloader with Metadata

Give this actor a video link, a playlist, a channel, or even a search phrase, and it resolves every video behind it, downloads each at your chosen quality, and hands back a public link to the file alongside the video's title, stats and description.

### What this actor does

- **Download videos** from direct URLs, playlists, channels, or search results
- **Quality options:** best available, 1080p, 720p, 480p, 360p, audio-only, or lowest
- **Subtitles:** download caption files in one or more languages
- **Metadata-only mode:** get full metadata without downloading the file
- **Empty fields are omitted** — records only contain values that are actually populated (empty lists such as `subtitle_files` are left out too).

### Output

Each video produces one record in the output dataset. Here is an example of a single output record:

```json
{
    "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "video_id": "dQw4w9WgXcQ",
    "title": "Rick Astley - Never Gonna Give You Up (Official Music Video)",
    "description": "The official video for Never Gonna Give You Up by Rick Astley...",
    "uploader": "Rick Astley",
    "uploader_id": "@RickAstleyYT",
    "uploader_url": "https://www.youtube.com/@RickAstleyYT",
    "upload_date": "2009-10-25",
    "duration_seconds": 212.0,
    "view_count": 1400000000,
    "like_count": 16000000,
    "comment_count": 2200000,
    "thumbnail": "https://api.apify.com/v2/key-value-stores/.../records/yt_dQw4w9WgXcQ_thumb.jpg",
    "tags": ["rick astley", "never gonna give you up", "80s"],
    "categories": ["Music"],
    "resolution": "1280x720",
    "filesize_bytes": 28491776,
    "download_status": "success",
    "download_url": "https://api.apify.com/v2/key-value-stores/.../records/yt_dQw4w9WgXcQ.mp4",
    "storage_key": "yt_dQw4w9WgXcQ.mp4",
    "source_label": "direct",
    "record_type": "result",
    "downloaded_at": "2026-02-23T10:00:00Z"
}
```

#### Output fields

| Field | Description |
| --- | --- |
| `video_url` | URL of the YouTube video |
| `video_id` | YouTube video ID |
| `title` | Title of the video |
| `description` | Video description (up to 2000 characters) |
| `uploader` | Channel or uploader name |
| `uploader_id` | Channel or uploader ID |
| `uploader_url` | URL of the uploader's channel |
| `upload_date` | Upload date (YYYY-MM-DD) |
| `duration_seconds` | Duration of the video in seconds |
| `view_count` | Number of views |
| `like_count` | Number of likes |
| `comment_count` | Number of comments |
| `thumbnail` | URL of the video thumbnail (a stored copy after a successful download, YouTube's own image URL otherwise) |
| `tags` | Tags associated with the video |
| `categories` | Categories associated with the video |
| `resolution` | Resolution of the downloaded video (e.g. 1920x1080) |
| `filesize_bytes` | File size of the downloaded video in bytes |
| `is_live` | Whether the video is a live or upcoming broadcast |
| `video_meta` | Technical detail about the downloaded file: `width`, `height`, `fps`, `vcodec`, `acodec`, `ext`, `filesize_bytes`, `total_bitrate_kbps`, `aspect_ratio` (audio-only downloads omit the video-specific keys) |
| `download_status` | Status: `success`, `failed`, `no_video` (the download finished without a usable video file), `upload_failed` (downloaded but the file couldn't be stored), or `metadata_only` |
| `download_url` | Public URL to download the video file |
| `storage_key` | Key of the video file in storage |
| `subtitle_files` | List of subtitle file keys |
| `subtitle_urls` | List of public URLs for subtitle files |
| `source_label` | Input source label (`direct`, `playlist:…`, `channel:…`, or `search:…`) |
| `record_type` | Always `result` for dataset rows |
| `search_query` | Search phrase on a failure row for a search that returned no videos |
| `error` | Error message if the download, metadata read or input resolution failed |
| `downloaded_at` | Timestamp of when the download was processed |

Besides one row per video, the dataset can contain failure rows (`download_status: "failed"` with an `error`): one for each playlist or channel that resolves to no videos (its URL is in `video_url`), one for each search phrase with no results (in `search_query`), and a single row when no input was given at all. Videos that are private, removed, unavailable or blocked for copyright are skipped without a row when downloading.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `videoUrls` | array | — | Direct YouTube video URLs to download. |
| `playlistUrls` | array | — | YouTube playlist URLs — videos in the playlist are processed up to `maxVideosPerInput`. |
| `channelUrls` | array | — | YouTube channel URLs, handles, or IDs. |
| `searchQueries` | array | — | Search phrases; up to `maxVideosPerInput` public matches per phrase are resolved, never more than 50. |
| `videoQuality` | string | `720p` | `best`, `1080p`, `720p`, `480p`, `360p`, `audio_only`, or `worst`. Falls back to the best available quality when the chosen one doesn't exist, and to the lowest quality if the file would not fit in the run's disk space. |
| `maxVideosPerInput` | integer | `10` | Maximum videos processed per playlist, channel, or search input (1–500; searches stop at 50). Direct video URLs are not limited. |
| `downloadSubtitles` | boolean | `false` | Download subtitle files alongside the video. |
| `subtitleLanguages` | array | `["en"]` | Subtitle language codes to fetch when `downloadSubtitles` is on. |
| `extractMetadataOnly` | boolean | `false` | Return metadata without downloading the video file. |
| `proxyCountry` | string | `US` | Country of the built-in residential proxy (31 options) — change if a video is geo-blocked. |
| `cookies` | string | — | Optional Netscape-format `cookies.txt` content for age-restricted or members-only videos (not needed for public videos). |

#### Example input

```json
{
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "videoQuality": "720p",
    "downloadSubtitles": false,
    "maxVideosPerInput": 10,
    "proxyCountry": "US"
}
```

Search example:

```json
{
    "searchQueries": ["python tutorial for beginners"],
    "maxVideosPerInput": 3,
    "videoQuality": "480p",
    "extractMetadataOnly": true
}
```

#### How to use

1. **Add your YouTube URLs** — paste video URLs, playlist URLs, or channel URLs into the corresponding input fields.
2. **Choose video quality** — select your preferred resolution from the dropdown (defaults to 720p).
3. **Configure options** — optionally enable subtitle downloads, set a max video limit for playlists/channels, or change the proxy country.
4. **Run the actor** — click Start and the actor will process each video, downloading and storing the files.
5. **Access your results** — find all downloaded videos and metadata in the dataset. Each successfully downloaded video includes a public download link.

### Examples

#### Example: single video

```json
{
  "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "videoQuality": "720p"
}
```

#### Example: playlist with subtitles

```json
{
  "playlistUrls": ["https://www.youtube.com/playlist?list=PL-osiE80TeTt2d9bfVyTiXJA-UTHn6WwU"],
  "maxVideosPerInput": 5,
  "downloadSubtitles": true,
  "subtitleLanguages": ["en", "es"]
}
```

#### Example: metadata only

```json
{
  "searchQueries": ["lofi beats"],
  "maxVideosPerInput": 10,
  "extractMetadataOnly": true
}
```

### Use cases

- **Content archival** — back up your favorite YouTube videos or entire channels before they disappear.
- **Research and analysis** — collect video metadata (titles, descriptions, view counts, tags) at scale for content research, trend analysis, or competitive intelligence.
- **Media production** — download source material for editing, compilation, or repurposing (always respect copyright).
- **Subtitle extraction** — grab caption files for translation, accessibility, or content repurposing workflows.
- **Audio extraction** — download podcast episodes, music, or audio content from YouTube without the video.
- **Dataset building** — build structured datasets of YouTube video metadata for machine learning or analytics projects.

### FAQ

#### How do I download a single YouTube video?

Paste the video URL into the **Video URLs** field and click Start. The actor will download the video and provide a public link to the file along with all available metadata.

#### Can I download an entire YouTube playlist?

Yes. Paste the playlist URL into the **Playlist URLs** field. The actor will automatically expand the playlist and download each video. Use **Max Videos Per Playlist / Channel** to limit the number of videos.

#### Can I download videos from a YouTube channel?

Yes. Paste the channel URL (e.g. `https://www.youtube.com/@ChannelName`) into the **Channel URLs** field. The actor will fetch the latest videos from that channel.

#### Can I download videos from a YouTube search?

Yes. Add search phrases to **Search Queries**. Each phrase is resolved through
YouTube's public search results, capped at `maxVideosPerInput` and never more than 50 results per phrase, and
processed the same way as direct URLs.

#### What video qualities are available?

You can choose from: Best Available, 1080p, 720p, 480p, 360p, Audio Only (no video), or Lowest (fastest download). If the selected quality is not available for a particular video, the actor automatically falls back to the best available option. If a very large file would not fit in the run's disk space, it downloads the lowest quality instead.

#### Can I download just the audio from a YouTube video?

Yes. Set the **Video Quality** to "Audio Only" and the actor will download only the audio track.

#### Can I download subtitles?

Yes. Enable the **Download Subtitles** option and the actor will download available caption files alongside the video. Subtitle files are stored separately with their own public URLs.

#### What if a video is geo-blocked in my region?

Change the **Proxy Country** setting to a country where the video is available. There are 31 options, including the United States, United Kingdom, Germany, France, Canada, Australia, Japan, India, Brazil, and Singapore.

#### Where are the downloaded files stored?

Downloaded video files are uploaded to the Apify Key-Value Store. Each successfully downloaded video includes a `download_url` field in the output — this is a public link you can use to access the file directly.

#### What happens if a download fails?

The output record for that video will have a `download_status` of `failed` along with an `error` field explaining what went wrong, and the actor continues with the remaining videos. The exception is a video that is private, removed, unavailable or blocked for copyright: it is skipped without a dataset row.

#### Can I get video metadata without downloading the actual file?

Yes. Download rows include the video's metadata (title, description, view counts, likes, tags, upload date, etc.) whenever it could be read, and a failed row may carry only the URL and the error.

Enable the **Metadata Only (No Download)** option to skip the download entirely and get metadata in seconds — no storage is consumed.

#### Is this affiliated with YouTube?

No. This is an independent tool and is not affiliated with, endorsed by, or sponsored by YouTube or Google.

# Actor input Schema

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

YouTube video URLs to download.

## `videoQuality` (type: `string`):

Preferred quality. Automatically falls back to the best available quality if the chosen resolution is unavailable. We highly recommend choosing 1080p or less for resolution for keeping the cost low. Higher the quality, higher the cost.

## `downloadSubtitles` (type: `boolean`):

Download subtitle / caption files (English) alongside the video.

## `playlistUrls` (type: `array`):

YouTube playlist URLs - all videos in each playlist will be downloaded.

## `channelUrls` (type: `array`):

YouTube channel URLs (e.g. https://www.youtube.com/@ChannelName).

## `searchQueries` (type: `array`):

Optional YouTube searches. The actor resolves up to maxVideosPerInput public video results per query.

## `maxVideosPerInput` (type: `integer`):

Maximum number of videos to download per playlist, channel, or search query. Does not affect direct video URLs.

## `proxyCountry` (type: `string`):

Country for the residential proxy IP. Change this if a video is geo-blocked in the default country.

## `extractMetadataOnly` (type: `boolean`):

When enabled, extracts video metadata (title, description, view count, etc.) without downloading the actual video file. Much faster and uses no storage.

## `subtitleLanguages` (type: `array`):

Subtitle language codes to download when Download Subtitles is enabled.

## `cookies` (type: `string`):

Optional Netscape-format cookies.txt content for accessing age-restricted or members-only videos. Export from your browser using a cookies extension.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "videoQuality": "1080p",
  "downloadSubtitles": false,
  "searchQueries": [
    "python tutorial for beginners"
  ],
  "maxVideosPerInput": 1,
  "proxyCountry": "US",
  "extractMetadataOnly": true,
  "subtitleLanguages": [
    "en"
  ]
}
```

# Actor output Schema

## `downloads` (type: `string`):

Dataset containing all scraped download results with files, metadata, and subtitles.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videoUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "videoQuality": "1080p",
    "downloadSubtitles": false,
    "searchQueries": [
        "python tutorial for beginners"
    ],
    "maxVideosPerInput": 1,
    "extractMetadataOnly": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/youtube-video-playlist-and-channel-downloader").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "videoUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
    "videoQuality": "1080p",
    "downloadSubtitles": False,
    "searchQueries": ["python tutorial for beginners"],
    "maxVideosPerInput": 1,
    "extractMetadataOnly": True,
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/youtube-video-playlist-and-channel-downloader").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videoUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "videoQuality": "1080p",
  "downloadSubtitles": false,
  "searchQueries": [
    "python tutorial for beginners"
  ],
  "maxVideosPerInput": 1,
  "extractMetadataOnly": true
}' |
apify call nimbryxo-studio/youtube-video-playlist-and-channel-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/youtube-video-playlist-and-channel-downloader"
        }
    }
}
```

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/2Dxwy6cHWqWRHqhC9/builds/JUaqrOIN08sc1v4xe/openapi.json
