Use YouTube Video, Playlist & Channel Downloader with Metadata with Python
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.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"allow4K": false,
"audioFormat": "m4a",
"audioOnly": false,
"channelUrls": [],
"container": "auto",
"downloadSubtitles": false,
"includeTranscript": false,
"kvsName": "",
"maxMB": 100,
"maxMinutes": 30,
"maxVideos": 1,
"mode": "metadata",
"playlistUrls": [],
"proxyConfiguration": {
"useApifyProxy": true
},
"s3Prefix": "youtube-downloader",
"s3Region": "auto",
"searchQueries": [],
"storage": "ephemeral_kvs",
"storageRetentionDays": 7,
"subtitleFormat": "vtt",
"subtitleLanguages": [
"en"
],
"videoQuality": "360p",
"videoUrls": [
"https://www.youtube.com/watch?v=jNQXAC9IVRw"
]
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | required | What to return: metadata only, media files, or caption files without media. |
videoUrls | array | optional | Direct YouTube video, Shorts, live-replay, or youtu.be URLs, or 11-character video IDs. |
playlistUrls | array | optional | YouTube playlist URLs. Videos are expanded up to maxVideos in total. |
channelUrls | array | optional | YouTube channel URLs, @handles, or UC channel IDs. The Videos tab is used. |
searchQueries | array | optional | YouTube search phrases. Each query resolves public results up to maxVideos in total. |
videoQuality | string | optional | SDR target quality. 360p-1080p prefer H.264/AAC MP4. 1440p and 2160p require allow4K and are delivered with their real codec and container. |
container | string | optional | Auto uses MP4 H.264/AAC when available and MKV for VP9/AV1. Explicit MP4 never relabels AV1/Opus content as MP4; if no compatible stream exists the video gets a failure row. |
audioOnly | boolean | optional | Download the source audio track without video and without re-encoding. |
audioFormat | string | optional | Source audio passthrough format used when audioOnly is enabled. |
downloadSubtitles | boolean | optional | Fetch available manual or automatic captions for the requested languages. |
subtitleLanguages | array | optional | Caption language codes to request. Only tracks that already exist on the video are used; translations are not promised. |
subtitleFormat | string | optional | File format for downloaded captions. |
includeTranscript | boolean | optional | Add a plain-text transcript from the first requested caption track. |
maxVideos | integer | optional | Total videos processed across all inputs. |
maxMinutes | integer | optional | Reject a video before download when its duration exceeds this cap. 4K opt-in downloads are additionally capped at 10 minutes. |
maxMB | integer | optional | Reject oversized downloads. Values above 500 are only used for 4K opt-in downloads, which are capped at 1000 MB. |
allow4K | boolean | optional | Enable 1440p/2160p SDR downloads. These are capped at 10 minutes and 1000 MB and may use MKV with VP9/AV1 because YouTube rarely serves H.264 above 1080p. |
storage | string | optional | Where downloaded files are written. Named KVS persists while the store exists; ephemeral KVS follows your Apify account retention. |
kvsName | string | optional | Named key-value store name when storage=named_kvs. Defaults to youtube-downloader. |
storageRetentionDays | integer | optional | Signed-link lifetime for S3/R2 storage (1-7 days). KVS retention is controlled by your Apify account. |
s3Bucket | string | optional | Bucket name when storage=s3. |
s3Prefix | string | optional | Object key prefix when storage=s3. |
s3Endpoint | string | optional | Custom endpoint for S3-compatible storage such as Cloudflare R2. |
s3Region | string | optional | Region for S3 or S3-compatible storage. |
s3AccessKeyId | string | optional | Optional access key ID when storage=s3. |
s3SecretAccessKey | string | optional | Optional secret access key when storage=s3. |
s3PublicBaseUrl | string | optional | Optional public bucket URL. When set, files use public URLs instead of expiring presigned URLs. |
cookies | string | optional | Optional cookies.txt content for age-restricted or members-only videos. Public videos work without cookies. |
proxyConfiguration | object | optional | Optional. Metadata and player extraction use this connection; media bytes are downloaded directly. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/2Dxwy6cHWqWRHqhC9/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
YouTube video metadata, media files, captions, transcripts, and honest failure rows.
Questions before you run
Which inputs are required?
The published required fields are mode
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build tyaMzg62TcJZfZ4Pv and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.