# YouTube Authorized 4K Video Downloader (`automation-lab/youtube-4k-video-downloader`) Actor

Download authorized public YouTube videos up to 4K and export stored files with video, channel, format, resolution, and retrieval metadata.

- **URL**: https://apify.com/automation-lab/youtube-4k-video-downloader.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Videos
- **Stats:** 2 total users, 1 monthly users, 57.1% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $22.08 / 1,000 10 mb downloadeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Authorized 4K Video Downloader

Download authorized, anonymously playable **YouTube 4K videos** in the best available resolution up to 2160p. The Actor selects compatible video and audio streams, merges them when necessary, stores the finished MP4 or Matroska file in Apify storage, and exports typed video, channel, format, resolution, file-size, and retrieval metadata.

Use it for owned-channel backups, rights-cleared production assets, client-approved archives, and repeatable media pipelines. It does not accept cookies or bypass private, paid, DRM, age-restricted, or login-only access controls.

### What does this YouTube video downloader do?

For every supplied video URL, the Actor:

1. validates and canonicalizes the YouTube URL;
2. resolves anonymous player metadata with current `yt-dlp` extraction;
3. selects the highest available non-DRM video at or below `maxHeight`;
4. selects compatible audio and merges streams with ffmpeg when needed;
5. enforces the requested file-size safety limit;
6. stores the completed media file in the run key-value store;
7. writes one typed retrieval record to the default dataset.

Every successful item creates a stored media file. Choose a lower `maxHeight` or tighter `maxVideoSizeMb` for small validation runs before downloading large 4K assets.

### Who is it for?

- **Creators and channel owners** backing up videos they own.
- **Production teams** retrieving licensed YouTube source assets.
- **Agencies** archiving videos with a client's permission.
- **Developers** connecting authorized downloads to storage or processing pipelines.
- **Archivists** preserving public, rights-cleared media with provenance metadata.

This Actor is URL-driven. It does not search YouTube, discover channel uploads, or monitor channels for new videos.

### Why use this Actor?

A normal player page does not provide a durable media file or a structured audit row. This Actor combines format selection, video/audio merging, bounded retries, Apify storage, and dataset metadata in one run.

The route is deliberately conservative:

- sequential processing limits upstream pressure;
- direct retrieval is attempted first;
- a bounded US residential session is used only after a verified YouTube block;
- proof-of-origin tokens are generated inside the Actor container;
- no buyer cookies, account credentials, or private session data are accepted;
- failures remain visible in the dataset and a completely unsuccessful run fails.

### What data does it return?

| Field | Meaning |
| --- | --- |
| `videoId` | Stable 11-character YouTube video ID |
| `title` | Public video title |
| `channel`, `channelId` | Publishing channel identity |
| `durationSeconds`, `uploadDate` | Duration and public upload date |
| `sourceUrl` | Canonical YouTube watch URL |
| `requestedMaxHeight` | Input resolution ceiling |
| `width`, `height`, `resolution` | Selected video dimensions |
| `format` | Final or planned container, such as `mp4` |
| `videoCodec`, `audioCodec` | Selected stream codecs |
| `formatIds` | Selected yt-dlp video/audio format IDs |
| `fileSizeBytes` | Final stored file size in bytes |
| `videoFileKey`, `videoFileUrl` | Apify storage key and API URL |
| `retrievalMode` | `direct` or bounded `residential` route |
| `chargedDownloadUnits` | Started 10 MB units for a saved file |
| `retrievalStatus` | `downloaded` or `failed` |
| `error`, `retrievedAt` | Bounded error and observation timestamp |

Fields that YouTube does not expose are returned as `null`; field names remain stable for integrations.

### How much does it cost to download authorized YouTube videos?

Pay-per-event billing tracks successful stored-media volume:

- one **Start** event per run: **$0.005**;
- one **10 MB downloaded** event per started 10 MB of a successfully stored file: **$0.0368** at BRONZE.

Examples at BRONZE pricing:

| Workflow | Event calculation | Actor charge |
| --- | --- | ---: |
| Save an 11.3 MB video | start + 2 download units | $0.0786 |
| Save an approximately 240 MB 4K video | start + 24 download units | $0.8882 |

The Actor charges download units only after a file is stored successfully. Actual file size depends on duration, resolution, and codec. Apify platform storage retention and data transfer may create separate infrastructure usage outside Actor PPE events.

### Getting started

1. Open the Actor input page.
2. Add one or more public YouTube video URLs.
3. Enable **I am authorized to download these videos**.
4. Choose a maximum height from 360 through 2160.
5. Set a file-size limit that fits your workflow.
6. Start the run.
7. Open **Video metadata** for dataset rows and **Downloaded files** for media.

Begin with one short video and a lower resolution before processing larger assets.

### Input parameters

| Input | Type | Default | Details |
| --- | --- | --- | --- |
| `startUrls` | array | required | Up to 20 YouTube watch, Shorts, replay, embed, or youtu.be URLs |
| `confirmAuthorizedUse` | boolean | `false` | Must be `true`; confirms your authorization |
| `maxHeight` | integer | `1080` | One of 360, 480, 720, 1080, 1440, or 2160 |
| `maxVideoSizeMb` | integer | `100` | Per-file safety limit from 1 to 500 MB |
| `maxItems` | integer | `10` | Maximum unique videos, from 1 to 20 |
| `maxRequestRetries` | integer | `1` | Bounded transient retries, from 0 to 3 |

Duplicate video IDs are processed once. Playlist URLs are not expanded.

### Example input

```json
{
  "startUrls": [
    { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
  ],
  "confirmAuthorizedUse": true,
  "maxHeight": 720,
  "maxVideoSizeMb": 50,
  "maxItems": 1,
  "maxRequestRetries": 1
}
```

### Example output

```json
{
  "videoId": "dQw4w9WgXcQ",
  "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
  "channel": "Rick Astley",
  "durationSeconds": 213,
  "sourceUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
  "requestedMaxHeight": 720,
  "width": 1280,
  "height": 720,
  "resolution": "1280x720",
  "format": "mp4",
  "videoCodec": "avc1.64001F",
  "audioCodec": "mp4a.40.2",
  "formatIds": ["136", "140"],
  "fileSizeBytes": 29969207,
  "videoFileKey": "video-dQw4w9WgXcQ-720p.mp4",
  "videoFileUrl": "https://api.apify.com/v2/key-value-stores/example/records/video-dQw4w9WgXcQ-720p.mp4",
  "retrievalMode": "direct",
  "chargedDownloadUnits": 3,
  "retrievalStatus": "downloaded",
  "error": null,
  "retrievedAt": "2026-08-23T11:40:00.000Z"
}
```

Every successful result has `retrievalStatus: "downloaded"` and populated `videoFileKey` and `videoFileUrl`.

### Run from the API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~youtube-4k-video-downloader/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}],
    "confirmAuthorizedUse": true,
    "maxHeight": 720,
    "maxVideoSizeMb": 50,
    "maxItems": 1
  }'
```

For production, send the token in an `Authorization: Bearer` header rather than storing it in source code.

### Run from JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/youtube-4k-video-downloader').call({
  startUrls: [{ url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }],
  confirmAuthorizedUse: true,
  maxHeight: 720,
  maxVideoSizeMb: 50,
  maxItems: 1,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run from Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/youtube-4k-video-downloader').call(run_input={
    'startUrls': [{'url': 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'}],
    'confirmAuthorizedUse': True,
    'maxHeight': 720,
    'maxVideoSizeMb': 50,
    'maxItems': 1,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/youtube-4k-video-downloader"
```

Use the same JSON setup for **Claude Desktop**, **Cursor**, and **VS Code**:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/youtube-4k-video-downloader"
    }
  }
}
```

Example prompts:

- “Download this authorized public YouTube video at the best available resolution up to 4K.”
- “Archive these two rights-cleared YouTube source videos at up to 720p.”
- “Return the stored file URLs and provenance metadata for this creator backup.”

### Integration workflows

**Creator backup:** schedule a run with a maintained list of owned video URLs, then copy each `videoFileUrl` to long-term object storage.

**Production ingestion:** trigger the Actor from a content-management workflow, verify `retrievalStatus`, then pass the stored file to transcoding, transcription, or review.

**Bounded preflight:** run one short asset at 360p to validate storage and downstream processing before approving a larger archival batch.

**Audit trail:** retain dataset rows with canonical source URLs, channel IDs, selected formats, retrieval mode, and timestamps alongside your rights documentation.

### Limits and failure behavior

- Maximum 20 unique videos and 500 MB per file.
- Videos are processed sequentially to reduce blocking and memory pressure.
- 4K commonly uses separate video and audio streams and can produce large files.
- Active live, upcoming, DRM, private, members-only, login-only, age-restricted, and inaccessible geo-blocked videos are unsupported.
- YouTube can rotate player challenges; a source change may require an Actor update.
- Some videos have no 4K upload. The Actor selects the best available height below the requested ceiling.
- A failed input produces a `failed` dataset row with no download event charge.
- If every supplied input fails, the Actor run fails rather than reporting an empty success.

### Responsible and legal use

Only download videos you own, videos covered by a suitable license, or videos for which the rights holder has authorized your use. Public playback does not itself grant copyright permission.

Follow YouTube's terms, applicable copyright law, privacy obligations, contractual restrictions, and retention requirements. Do not use the Actor to bypass access controls, subscriptions, DRM, age gates, geographic restrictions, or private sharing settings. Keep authorization records for professional archival workflows.

### Troubleshooting

**The result says the video is login-only or restricted.**

Confirm the URL plays anonymously in the required geography. The Actor intentionally does not accept cookies or account credentials.

**The selected resolution is below 4K.**

The upload may not contain a 2160p format. Check `height`, `resolution`, and `formatIds`; the Actor chooses the best available format below `maxHeight`.

**The selected file exceeds the size limit.**

Increase `maxVideoSizeMb` up to 500 or lower `maxHeight` to select a smaller rendition.

**A run works for one video but not another.**

Restrictions are video-specific. Inspect each row's `error` field. Retry transient blocks, but do not retry private, DRM, or rights-related failures.

### Related Automation Lab Actors

- [YouTube Channel Videos Scraper](https://apify.com/automation-lab/youtube-channel-videos-scraper) — discover public video metadata from a channel before selecting authorized assets.
- [YouTube Thumbnail Downloader](https://apify.com/automation-lab/youtube-thumbnail-downloader) — save public thumbnail images without transferring video media.
- [Video to Text Transcriber](https://apify.com/automation-lab/video-to-text-transcriber) — turn an accessible stored video into timestamped transcript records.

### FAQ

**Does it guarantee 4K?**

No. It supports resolutions up to 2160p and selects the best format that the source actually exposes.

**Can I resolve formats without storing a file?**

No. This Actor is intentionally priced and scoped as a downloader; every successful item stores a completed media file.

**Can it download playlists or whole channels?**

No. Supply individual video URLs. Use a related channel scraper for discovery, then pass only authorized URLs into this Actor.

**Can I provide YouTube cookies?**

No. The Actor is intentionally limited to anonymous public playback and does not handle private user sessions.

**How long are files kept?**

Files use the run's default Apify key-value store and follow your Apify storage retention settings. Copy important archives to durable storage that matches your retention policy.

# Actor input Schema

## `startUrls` (type: `array`):

Public YouTube video, Shorts, live-replay, embed, or youtu.be URLs. Playlists, active live streams, private, login-only, age-restricted, and DRM content are not supported.

## `confirmAuthorizedUse` (type: `boolean`):

Confirm that you own the videos, have the rights holder's permission, or otherwise have legal authorization to archive them.

## `maxHeight` (type: `integer`):

Select the best available video resolution at or below this height.

## `maxVideoSizeMb` (type: `integer`):

Reject a selected video before or after download when its merged size exceeds this safety limit.

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

Maximum number of unique supplied videos to process sequentially.

## `maxRequestRetries` (type: `integer`):

Bounded retries for transient YouTube or network failures.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=gHKT4uU8Zng"
    }
  ],
  "confirmAuthorizedUse": true,
  "maxHeight": 360,
  "maxVideoSizeMb": 10,
  "maxItems": 1,
  "maxRequestRetries": 1
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing one typed retrieval record per supplied video.

## `files` (type: `string`):

Key-value store containing downloaded MP4 or Matroska video files.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.youtube.com/watch?v=gHKT4uU8Zng"
        }
    ],
    "confirmAuthorizedUse": true,
    "maxHeight": 360,
    "maxVideoSizeMb": 10,
    "maxItems": 1,
    "maxRequestRetries": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/youtube-4k-video-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 = {
    "startUrls": [{ "url": "https://www.youtube.com/watch?v=gHKT4uU8Zng" }],
    "confirmAuthorizedUse": True,
    "maxHeight": 360,
    "maxVideoSizeMb": 10,
    "maxItems": 1,
    "maxRequestRetries": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/youtube-4k-video-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 '{
  "startUrls": [
    {
      "url": "https://www.youtube.com/watch?v=gHKT4uU8Zng"
    }
  ],
  "confirmAuthorizedUse": true,
  "maxHeight": 360,
  "maxVideoSizeMb": 10,
  "maxItems": 1,
  "maxRequestRetries": 1
}' |
apify call automation-lab/youtube-4k-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/youtube-4k-video-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/mEEBlgQ19qSDmOWsN/builds/EfmoitVjSoUs8DjcY/openapi.json
