# YouTube Playlist Scraper - Every Video with Views & Dates (`seemuapps/youtube-playlist-scraper`) Actor

Scrape every video in any YouTube playlist with title, position, duration, views, likes, comments, upload date, tags and channel - export to JSON, CSV or Google Sheets.

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

## Pricing

$2.00 / 1,000 playlist videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Playlist Scraper - Every Video with Views & Dates

Scrape every video in any public YouTube playlist, in order, with title, duration, view count, exact upload date, like and comment counts, tags, category and channel. Works on regular playlists, courses, series, podcast feeds and channel "uploads" lists of any size - thousands of videos in one run. No login, no cookies, no YouTube API quota to manage.

Give it playlist links and get one clean row per video, ready for JSON, CSV, Excel or Google Sheets.

### What you get

For every video in the playlist:

- **position** in the playlist, **videoId**, **url**, **title**, **isAvailable**
- **durationSeconds**, **publishedAt** (exact timestamp) and **publishedText** ("2 years ago")
- **viewCount**, **likeCount**, **commentCount**
- **description**, **tags**, **categoryId**, **language**, **hasCaptions**, **isLive**
- **channelId**, **channelTitle**, **channelUrl**, **thumbnailUrl**

Plus the playlist itself on every row: **playlistId**, **playlistUrl**, **playlistTitle**, **playlistOwner**, **playlistOwnerChannelId**, **playlistOwnerUrl**, **playlistVideoCount**, **playlistViewCount**, **playlistLastUpdated**.

### Use cases

- **Course and curriculum export** - turn a tutorial series into a spreadsheet with durations and links
- **Content audits** - see which videos in a series over- or under-perform on views and engagement
- **Competitor research** - map how a channel structures its playlists and where the traffic goes
- **Podcast and show archives** - build an episode index with dates and lengths
- **Watch-time planning** - total up durations for training material
- **Dataset building** - collect thousands of related videos with metadata in one run

### How to use

1. Enter one or more **Playlist URLs** - `playlist?list=...` links, `watch?v=...&list=...` links, or bare IDs such as `PLxxxx`.
2. Set **Max videos per playlist** (default `0` = every video).
3. Leave **Include full video details** on for exact dates, likes, comments, tags and descriptions; turn it off for a faster run with basic fields.
4. Optionally enable **Include private and deleted videos** to keep placeholder rows so positions stay contiguous.
5. Run the actor - videos stream into the **Dataset** tab in playlist order.

### Output format

```json
{
  "playlistId": "PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3",
  "playlistUrl": "https://www.youtube.com/playlist?list=PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3",
  "playlistTitle": "Python for Beginners (Full Course) | Programming Tutorial",
  "playlistOwner": "Telusko",
  "playlistOwnerChannelId": "UC59K-uG2A5ogwIrHw4bmlEg",
  "playlistOwnerUrl": "https://www.youtube.com/@Telusko",
  "playlistVideoCount": 124,
  "playlistViewCount": 56933267,
  "playlistLastUpdated": "Jun 12, 2026",
  "position": 1,
  "videoId": "QXeEoD0pB3E",
  "url": "https://www.youtube.com/watch?v=QXeEoD0pB3E&list=PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3",
  "title": "#0 Python for Beginners | Programming Tutorial",
  "isAvailable": true,
  "description": "Python is one of the best programming language and easy to learn...",
  "publishedAt": "2018-08-16T08:58:58Z",
  "publishedText": "8 years ago",
  "durationSeconds": 66,
  "viewCount": 9811772,
  "likeCount": 100619,
  "commentCount": 1248,
  "channelId": "UC59K-uG2A5ogwIrHw4bmlEg",
  "channelTitle": "Telusko",
  "channelUrl": "https://www.youtube.com/@Telusko",
  "thumbnailUrl": "https://i.ytimg.com/vi/QXeEoD0pB3E/maxresdefault.jpg",
  "tags": ["telusko", "python"],
  "categoryId": "28",
  "language": "en",
  "hasCaptions": true,
  "isLive": false
}
```

### Pricing

You pay a small fixed amount per video returned. Playlists that do not exist or are private cost nothing.

### Tips

- A channel's full upload history is a playlist too: replace the `UC` prefix of a channel ID with `UU` (for example `UU59K-uG2A5ogwIrHw4bmlEg`).
- Sort the CSV by **viewCount** to find the breakout episodes in a series.
- Sum **durationSeconds** to get the total length of a course.
- If YouTube begins blocking requests from the default network, enable **Proxy configuration** with Apify Proxy.

### FAQ

**Does it work on private or unlisted playlists?**
Unlisted playlists work if you have the link. Private playlists and Watch Later are not accessible.

**Why is a video's likeCount null?**
Some creators hide like counts; YouTube then returns nothing for that field.

**Can I scrape all videos from a channel instead?**
Use the `UU` playlist trick above, or the YouTube Channel Videos Scraper.

# Actor input Schema

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

YouTube playlist URLs or IDs, one per line. Accepts playlist?list=..., watch?v=...\&list=... and bare IDs such as PLxxxx. Up to 200 per run.

## `maxItemsPerPlaylist` (type: `integer`):

Videos to return from each playlist, in playlist order. 0 = every video, up to 20,000 per playlist.

## `includeVideoDetails` (type: `boolean`):

Adds exact upload date, like and comment counts, description, tags, category and caption availability for each video. Turn off for a faster, lighter run with title, duration, views and relative date only.

## `includeUnavailable` (type: `boolean`):

Also output placeholder rows for videos that are private or deleted (isAvailable = false) so positions stay contiguous.

## `country` (type: `string`):

Two-letter country code passed to YouTube, e.g. US, GB, AU. Affects regional availability.

## `language` (type: `string`):

Language code for YouTube's interface, e.g. en, de, pt-BR. Affects relative date text such as '2 weeks ago'.

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

Optional. Leave off by default. Enable Apify Proxy only if YouTube starts blocking requests from the default network.

## Actor input object example

```json
{
  "playlistUrls": [
    "https://www.youtube.com/playlist?list=PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3"
  ],
  "maxItemsPerPlaylist": 0,
  "includeVideoDetails": true,
  "includeUnavailable": false,
  "country": "US",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One record per video: playlistId, playlistUrl, playlistTitle, playlistOwner, playlistOwnerChannelId, playlistOwnerUrl, playlistVideoCount, playlistViewCount, playlistLastUpdated, position, videoId, url, title, isAvailable, description, publishedAt, publishedText, durationSeconds, viewCount, likeCount, commentCount, channelId, channelTitle, channelUrl, thumbnailUrl, tags, categoryId, language, hasCaptions, isLive.

# 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 = {
    "playlistUrls": [
        "https://www.youtube.com/playlist?list=PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("seemuapps/youtube-playlist-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 = { "playlistUrls": ["https://www.youtube.com/playlist?list=PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3"] }

# Run the Actor and wait for it to finish
run = client.actor("seemuapps/youtube-playlist-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 '{
  "playlistUrls": [
    "https://www.youtube.com/playlist?list=PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3"
  ]
}' |
apify call seemuapps/youtube-playlist-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,seemuapps/youtube-playlist-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/78NtHbQ5oL3R0lZyF/builds/kd9xOlykfkYbtrHOp/openapi.json
