# YouTube to MP3 Downloader (`khadinakbar/youtube-to-mp3-downloader`) Actor

Convert authorized YouTube videos and playlists to MP3 (or m4a, opus, wav, flac) with chosen bitrate, ID3 tags and thumbnail cover art. Saves each track to Apify key-value storage and returns MCP-ready JSON. Built for AI agents and SEO.

- **URL**: https://apify.com/khadinakbar/youtube-to-mp3-downloader.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Videos, MCP servers, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 audio file saveds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 to MP3 Downloader

Convert **authorized** YouTube videos and playlists into clean, tagged **MP3** files — or M4A, Opus, WAV, and FLAC — at the bitrate you choose. Every track is transcoded with `yt-dlp` + `ffmpeg`, tagged with ID3 metadata and embedded thumbnail cover art, saved to Apify key-value storage, and returned as MCP-ready JSON for AI agents and automation.

### What it does

Give it one or more YouTube URLs (single videos, Shorts, or playlists). For each track it:

1. Downloads the best available audio stream.
2. Transcodes to your chosen format and bitrate.
3. Embeds ID3 tags (title, artist, upload date) and the video thumbnail as cover art.
4. Saves the file to the key-value store and returns a structured row with a direct download key.

### When to use it

- Build an audio archive of talks, lectures, podcasts, or interviews you have rights to.
- Turn a playlist you own into a set of tagged MP3s in one run.
- Feed audio into transcription, diarization, or music-analysis pipelines.
- Let an AI agent fetch YouTube audio as a structured tool call (MCP-ready).

**Do not** use it to download content you do not own or have permission to use. See the legal note below.

### Output

One dataset row per track, plus the audio file in the key-value store.

| Field | Description |
|---|---|
| `title` | Video / track title |
| `artist` | Uploader / channel (written to the ID3 artist tag) |
| `videoId` | YouTube video ID |
| `durationSeconds` | Track length |
| `audioFormat` | `mp3`, `m4a`, `opus`, `wav`, or `flac` |
| `bitrateKbps` | Target bitrate for lossy formats (null for VBR / lossless) |
| `fileKey` | Key-value store key to download the audio file |
| `fileSizeBytes` | Saved file size |
| `thumbnail` | Cover-art image URL |
| `uploadDate` | `YYYYMMDD` when available |
| `status` | `success`, `skipped`, or `failed` |
| `error` | Actionable message when a track could not be produced |
| `scrapedAt` | ISO 8601 timestamp |

Audio files are stored under keys like `audio-{videoId}-{slug}.mp3`. Each row's `fileKey` points to its file.

### Pricing

Pay per result (PPE):

- **Actor start** — $0.00005 per run
- **Audio file saved** — **$0.02 per track** successfully saved

Failed, skipped, and invalid URLs are **not** charged the per-track fee. A typical single-track run costs about $0.02. You also pay Apify platform compute + proxy usage.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `videoUrls` | array | — | YouTube video / playlist URLs (required) |
| `authorizationConfirmed` | boolean | `false` | Must be `true` to download |
| `audioFormat` | enum | `mp3` | `mp3`, `m4a`, `opus`, `wav`, `flac` |
| `audioBitrate` | enum | `192` | `best`, `320`, `256`, `192`, `128` (lossy only) |
| `embedMetadata` | boolean | `true` | ID3 tags + thumbnail cover art |
| `includePlaylist` | boolean | `false` | Expand playlist URLs |
| `maxResults` | integer | `20` | Total track cap per run (1–200) |
| `maxDurationMinutes` | integer | `120` | Skip longer videos |
| `maxFileSizeMb` | integer | `100` | Skip larger files |
| `includeMetadataJson` | boolean | `false` | Save raw yt-dlp metadata JSON |
| `cookiesTxt` | string (secret) | — | Netscape cookies.txt for restricted videos |
| `proxyConfiguration` | object | Residential | Apify proxy settings |

#### Example input

```json
{
  "videoUrls": [{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }],
  "authorizationConfirmed": true,
  "audioFormat": "mp3",
  "audioBitrate": "192",
  "embedMetadata": true
}
```

#### Playlist example

```json
{
  "videoUrls": [{ "url": "https://www.youtube.com/playlist?list=PLxxxxxxxx" }],
  "authorizationConfirmed": true,
  "includePlaylist": true,
  "maxResults": 25,
  "audioFormat": "mp3",
  "audioBitrate": "320"
}
```

### Use with the Apify API

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("khadinakbar/youtube-to-mp3-downloader").call(run_input={
    "videoUrls": [{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}],
    "authorizationConfirmed": True,
    "audioFormat": "mp3",
    "audioBitrate": "192",
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["title"], row["fileKey"], row["status"])
```

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('khadinakbar/youtube-to-mp3-downloader').call({
    videoUrls: [{ url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }],
    authorizationConfirmed: true,
    audioFormat: 'mp3',
    audioBitrate: '192',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Download a saved file from the key-value store using its `fileKey`:

```
https://api.apify.com/v2/key-value-stores/{storeId}/records/{fileKey}
```

### MCP and AI agents

This actor is MCP-ready. It returns compact, flat JSON with stable keys and a direct `fileKey` for each track, so agents can request YouTube audio as a single tool call and hand the file to a downstream transcription or analysis step. Expose it via `https://mcp.apify.com?tools=khadinakbar/youtube-to-mp3-downloader`.

### FAQ

**Which format should I pick?** MP3 for maximum compatibility, M4A/Opus for smaller high-quality files, WAV/FLAC when you need lossless audio for editing.

**Does it embed cover art?** Yes, when `embedMetadata` is on (default). The video thumbnail is embedded and ID3 tags are written.

**Can it download a whole playlist?** Yes — set `includePlaylist: true` and raise `maxResults`. The cap applies to the whole run to keep cost predictable.

**Why residential proxy?** YouTube heavily rate-limits datacenter IPs. Residential proxy is the default for reliability.

**Age-restricted or members-only videos?** Provide your own `cookiesTxt` (Netscape format). Only use cookies you are allowed to use.

**A video returned "restricted\_media"?** Some premium/VEVO music and age-restricted videos are DRM-gated by YouTube and cannot be downloaded without a logged-in session. The run still succeeds and marks that track `skipped` with a clear message. To download it, supply `cookiesTxt` from an account allowed to view it. The vast majority of YouTube content (regular videos, talks, lectures, Shorts, most music, Creative Commons) downloads without cookies.

### Legal

This actor is a technical tool for downloading audio you own or are legally permitted to download. You are solely responsible for how you use it and for complying with YouTube's Terms of Service and all applicable copyright laws. Downloading copyrighted content without permission may be illegal in your jurisdiction. The `authorizationConfirmed` checkbox must be set to `true` to confirm you have the necessary rights. This actor does not bypass paywalls, DRM, or access controls.

# Actor input Schema

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

Full YouTube URLs to convert to audio, for example https://www.youtube.com/watch?v=dQw4w9WgXcQ. Accepts youtube.com/watch, youtu.be, Shorts, embed and (with the playlist toggle) playlist URLs. Defaults to one sample URL. NOT a search query or channel scraper.

## `authorizationConfirmed` (type: `boolean`):

Confirms you own the audio, have the rights holder's permission, or are otherwise legally allowed to download it. The run stops with a warning and downloads nothing when this is false. Defaults to false so accidental runs never download media. NOT a way to bypass YouTube rights or access controls.

## `audioFormat` (type: `string`):

Output audio format for every track. mp3 is the most compatible, m4a/opus are efficient lossy formats, and wav/flac are lossless. Defaults to mp3. NOT a video format — this actor only produces audio.

## `audioBitrate` (type: `string`):

Target bitrate for lossy formats (mp3, m4a, opus). 320 is highest quality, 128 is smallest file, and best keeps the source quality using VBR. Defaults to 192. Ignored for lossless wav and flac.

## `embedMetadata` (type: `boolean`):

Write ID3 metadata (title, artist, upload date) and embed the video thumbnail as cover art into each file. Defaults to true so files show up correctly in music players. Turn off for slightly faster, smaller, tag-free files. NOT related to the separate raw metadata JSON option.

## `includePlaylist` (type: `boolean`):

When on, a playlist URL is expanded and every track (up to the max results cap) is downloaded. When off, only the single video in the URL is used. Defaults to false. NOT a channel crawler — it only follows the specific playlist you provide.

## `maxResults` (type: `integer`):

Hard cap on the total number of audio tracks saved across all input URLs and expanded playlists. Defaults to 20 and accepts 1 to 200. Use this to bound cost, because each saved track is billed. NOT a per-playlist limit — it applies to the whole run.

## `maxDurationMinutes` (type: `integer`):

Skip videos longer than this many minutes before downloading. Defaults to 120 minutes and accepts 1 to 720. Use it to avoid long livestreams or podcasts. NOT a clip length — the actor downloads the full track when it passes this cap.

## `maxFileSizeMb` (type: `integer`):

Delete and mark a track as skipped if the final audio file is larger than this limit. Defaults to 100 MB and accepts 1 to 500. Lower it for agent workflows where small files matter. NOT a compression target.

## `includeMetadataJson` (type: `boolean`):

Also save the full yt-dlp metadata JSON for each successful track to the key-value store. Useful for audits and downstream processing. Defaults to false to keep storage lean. NOT required for the dataset row, which always includes concise metadata.

## `cookiesTxt` (type: `string`):

Optional Netscape cookies.txt content for age-restricted or members-only videos that need your logged-in YouTube session. Paste only cookies you are allowed to use. Leave empty for public videos. NOT a username or password field.

## `proxyConfiguration` (type: `object`):

Apify proxy used for YouTube requests. Residential proxies are enabled by default because datacenter IPs are frequently blocked by YouTube. Change only if you know your target videos work from another network.

## Actor input object example

```json
{
  "videoUrls": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "authorizationConfirmed": true,
  "audioFormat": "mp3",
  "audioBitrate": "192",
  "embedMetadata": true,
  "includePlaylist": false,
  "maxResults": 20,
  "maxDurationMinutes": 120,
  "maxFileSizeMb": 100,
  "includeMetadataJson": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `trackRows` (type: `string`):

Structured dataset rows with metadata, audio file keys, status and errors.

## `audioFiles` (type: `string`):

Downloaded audio and metadata files in the default key-value store.

## `summary` (type: `string`):

Machine-readable outcome, persisted row counts, and billed audio count.

## `runSummary` (type: `string`):

Detailed terminal contract for agents, automation, and support.

# 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": [
        {
            "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
        }
    ],
    "authorizationConfirmed": true,
    "audioFormat": "mp3",
    "audioBitrate": "192",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/youtube-to-mp3-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": [{ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }],
    "authorizationConfirmed": True,
    "audioFormat": "mp3",
    "audioBitrate": "192",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/youtube-to-mp3-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": [
    {
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    }
  ],
  "authorizationConfirmed": true,
  "audioFormat": "mp3",
  "audioBitrate": "192",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call khadinakbar/youtube-to-mp3-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/youtube-to-mp3-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/RbbDq6FqaoDSRJ50w/builds/hbhUZ7GWKdhEu6XeV/openapi.json
