# YouTube Playlist Videos – Links, Order & Metadata (`scrapingmonkey/youtube-playlist-videos-scraper`) Actor

Export video entries from YouTube playlists. Get titles, links, positions, availability flags, durations, thumbnails, and playlist context with configurable pagination.

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

## Pricing

from $1.00 / 1,000 results

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

Export the video entries exposed inside a YouTube playlist. **YouTube Playlist Videos Scraper** collects links, titles, available durations and view labels, playlist positions, and entry-level availability flags from full playlist links.

Each playlist entry becomes one row with its source-playlist context. Set a result-page limit to control how far the collection follows the playlist.

| At a glance | Details |
| --- | --- |
| 📥 Input | Full YouTube URLs containing list |
| 📤 Output | Playlist video entries, titles, order, availability flags, thumbnails, and playlist context |
| 🔐 Login required | No |
| 📄 Collection | Configurable result pages per input |
| 💾 Delivery | One row per playlist entry result, in one table |

### What the YouTube playlist videos scraper collects 🔎

The Actor follows the playlist's visible video list and preserves entry context as well as video-card metadata.

- Video ID, watch URL, title, and available description snippet
- Playlist ID, displayed playlist index, entry identifier, and saved-result position
- Available duration, view label, publication text, and badges
- Playable and unavailable flags for entries exposed by YouTube
- Thumbnail variants and available author identity
- Source-playlist title, description, counts, owner, and other exposed metadata

A recognizable private or deleted-video placeholder can be kept as a listed entry. The Actor does not restore hidden videos, fetch their contents, or download media.

### How to scrape YouTube playlist videos 🚀

1. Prepare the full playlist links you want to collect.
2. Add them to `inputList`, one value per item.
3. Set `pagesPerInput` and start the Actor.
4. Check `status` and export the fields needed for your workflow.

```json
{
  "inputList": [
    "https://www.youtube.com/playlist?list=PL2aBZuCeDwlRxnw-jDj51gmtBuCVZbsaZ"
  ],
  "pagesPerInput": 1
}
```

### YouTube playlist videos data fields and output 📦

| Field group | Included data |
| --- | --- |
| Video entry | Video ID, URL, title, listing fields, and author |
| Playlist position | Playlist ID, displayed index, entry identifier, and saved-result order |
| Availability | Playable and unavailable flags from the visible entry |
| Media preview | Thumbnail variants, available duration, and public view labels |
| Source playlist | Title, description, counts, owner, and exposed metadata |

Complete illustrative success item. The fictional values below demonstrate the output and are not a live result:

```json
{
  "input": "https://www.youtube.com/playlist?list=PLtrailjournalroutes2026",
  "status": "success",
  "id": "TrailWalk01",
  "url": "https://www.youtube.com/watch?v=TrailWalk01",
  "type": "video",
  "title": "A quiet forest loop: route guide",
  "description": "A shaded forest loop with route notes at https://example.com/trail #hiking",
  "thumbnail_url": "https://example.com/trail-large.jpg",
  "thumbnails.url": [
    "https://example.com/trail-small.jpg",
    "https://example.com/trail-large.jpg"
  ],
  "thumbnails.width": [
    160,
    1280
  ],
  "thumbnails.height": [
    90,
    720
  ],
  "duration_seconds": 150,
  "duration_text": "2:30",
  "views": 123000,
  "views_text": "123K views",
  "published_text": "2 days ago",
  "badges": [],
  "is_live": false,
  "is_upcoming": false,
  "is_premiere": false,
  "is_members_only": false,
  "stream_status": null,
  "scheduled_start_time": null,
  "accessibility_text": "A quiet forest loop: route guide by Trail Journal",
  "author.id": "UCabcdefghijklmnopqrstuv",
  "author.name": "Trail Journal",
  "author.handle": "@TrailJournal",
  "author.url": "https://www.youtube.com/@TrailJournal",
  "author.avatar_url": "https://example.com/trail-large.jpg",
  "author.avatar_thumbnails.url": [
    "https://example.com/trail-small.jpg",
    "https://example.com/trail-large.jpg"
  ],
  "author.avatar_thumbnails.width": [
    160,
    800
  ],
  "author.avatar_thumbnails.height": [
    160,
    800
  ],
  "author.is_verified": false,
  "playlist_id": "PLtrailjournalroutes2026",
  "playlist_index": 1,
  "set_video_id": "set-video-1",
  "is_playable": true,
  "is_unavailable": false,
  "source_playlist.id": "PLtrailjournalroutes2026",
  "source_playlist.url": "https://www.youtube.com/playlist?list=PLtrailjournalroutes2026",
  "source_playlist.canonical_url": "https://www.youtube.com/playlist?list=PLtrailjournalroutes2026",
  "source_playlist.title": "Weekend Trail Guides",
  "source_playlist.description": "#hiking Route guides: https://example.com/trail",
  "source_playlist.thumbnail_url": "https://example.com/trail-large.jpg",
  "source_playlist.thumbnails.url": [
    "https://example.com/trail-small.jpg",
    "https://example.com/trail-large.jpg"
  ],
  "source_playlist.thumbnails.width": [
    160,
    1280
  ],
  "source_playlist.thumbnails.height": [
    90,
    720
  ],
  "source_playlist.videos_count": 25,
  "source_playlist.videos_count_text": "25 videos",
  "source_playlist.views": 500000,
  "source_playlist.views_text": "500K views",
  "source_playlist.updated_text": "Last updated yesterday",
  "source_playlist.privacy": "public",
  "source_playlist.is_unlisted": false,
  "source_playlist.is_family_safe": true,
  "source_playlist.available_countries": [
    "US",
    "GB"
  ],
  "source_playlist.author.id": "UCabcdefghijklmnopqrstuv",
  "source_playlist.author.name": "Trail Journal",
  "source_playlist.author.handle": "@TrailJournal",
  "source_playlist.author.url": "https://www.youtube.com/@TrailJournal",
  "source_playlist.author.avatar_url": "https://example.com/trail-large.jpg",
  "source_playlist.author.avatar_thumbnails.url": [
    "https://example.com/trail-small.jpg",
    "https://example.com/trail-large.jpg"
  ],
  "source_playlist.author.avatar_thumbnails.width": [
    160,
    800
  ],
  "source_playlist.author.avatar_thumbnails.height": [
    160,
    800
  ],
  "source_playlist.author.is_verified": false,
  "source_playlist.description_links": [
    "https://example.com/trail"
  ],
  "source_playlist.hashtags": [
    "#hiking"
  ],
  "position": 1
}
```

The table and JSON use the same flat field names, including literal dotted keys. playlist\_index is the playlist position exposed by YouTube; position is the running order of saved entries. They can differ when entries are omitted or unavailable. Thumbnail and avatar variants use aligned lists, while description links and hashtags remain ordinary lists in the same row.

Optional values can be `null`, empty strings, `false`, or empty lists. Missing counts are normally `null`; numeric values parsed from abbreviated labels remain approximate. Failed rows preserve `input` and `status` and set the result-data fields to `null`. `position` is the running order of saved results for that input, not a global ranking.

### Input requirements and coverage ⚙️

| Parameter | Type | Default | Rules |
| --- | --- | --- | --- |
| `inputList` | array of strings | Required | One or more full YouTube URLs containing a valid list parameter. Raw playlist IDs are not accepted. No fixed batch-size maximum. |
| `pagesPerInput` | integer | `1` | At least 1; no fixed upper bound. Limits result pages for each input. |

Playlist, watch, and youtu.be links are accepted when they include list. The playlist ID must contain at least eight letters, digits, underscores, or hyphens. Each result's `url` links to a video, while `source_playlist.url` identifies the playlist.

YouTube controls page size. Collection stops at the requested page limit or when the list ends, whichever comes first. The initial result page counts as page 1; each continuation uses another page. Repeated items within an input are skipped, but repeating the input itself starts a separate collection. Repeated appearances of a video in different playlist slots can remain separate entries.

### YouTube playlist videos use cases 🎯

#### Learning-resource exports

Turn a playlist into a catalogue of lesson titles, watch links, durations, and positions for a study or review workflow.

#### Playlist audits

Inspect visible private or deleted placeholders and playable flags when maintaining a curated collection.

#### Ordered content catalogues

Preserve playlist entry order and source attribution when importing known collections into a database.

#### Targeted video enrichment

Use collected watch URLs as input to Video Details, Video Comments, or Video Transcript for selected entries.

### Pricing and billable playlist entry rows 💰

Check the Actor's **Pricing** tab for the current pricing model and rate.

Under dataset-item pricing, each saved success or failed row can be billable. Automatic retry attempts do not independently add rows. The number of billable items follows saved results, not requested pages. A collection that ends without results or a failed request can produce a failed row; if a later page fails, earlier saved results remain.

Image variants and other list fields remain in their parent row and do not create separate dataset items.

### YouTube Playlist Videos Scraper API and integrations 🔌

Use the Actor ID from the **API** tab as $ACTOR\_ID and your Apify token as $APIFY\_TOKEN.

```bash
curl -X POST "https://api.apify.com/v2/acts/$ACTOR_ID/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"inputList":["https://www.youtube.com/playlist?list=PL2aBZuCeDwlRxnw-jDj51gmtBuCVZbsaZ"],"pagesPerInput":1}'
```

The request starts a run. Retrieve the dataset when it finishes, or use a completion webhook to send results to your application. Apify schedules can repeat collection; exports and integrations support JSON, CSV, Excel, Google Sheets, Make, and Zapier workflows.

### Reliability and limits ⚠️

Up to five requests run concurrently, with automatic retries for temporary failures. Invalid, unavailable, or unresolved inputs are visible as failed rows. YouTube can restrict public access or omit fields.

The playlist page controls which entries are exposed. Missing or restricted videos may be omitted entirely or shown as limited placeholders. Availability flags describe the listing and do not prove playback in every location. The Actor exports card-level metadata, so full descriptions, engagement totals, and exact publication dates may require a dedicated video lookup.

Pagination preserves results already saved, but a page limit, inaccessible continuation, or changing source list can leave a partial collection. A completed run does not prove that every historical item was available.

### Frequently asked questions ❓

#### Can I submit only a playlist ID?

No. Submit a full supported YouTube URL with the list parameter.

#### Does it preserve playlist order?

It keeps the displayed playlist\_index when available and assigns position in saved-result order. Those values may differ if YouTube omits entries.

#### Are duplicate videos removed?

Repeated occurrences in distinct playlist slots can remain separate entries. The Actor deduplicates repeated representations of the same entry within an input.

#### Can deleted or private videos appear?

Yes, when YouTube exposes an identifiable placeholder. Such an entry can have status success for its parsed listing while is\_unavailable is true.

#### Will it download the playlist?

No. It returns video-page URLs and metadata, not video files or a merged download.

#### How do I collect the playlist's description only?

Use YouTube Playlist Details Scraper for one metadata row per playlist without collecting video entries.

### Support, responsible use, and related actors 🛟

For support, share the run ID and a safe public example input through the Actor's support channel. Keep tokens and credentials out of messages.

Use public data and media within the privacy, copyright, and other obligations that apply to your project.

# Actor input Schema

## `inputList` (type: `array`):

Add full YouTube URLs containing the list parameter, including playlist, watch, and youtu.be links. Raw playlist IDs are not accepted.

## `pagesPerInput` (type: `integer`):

Number of result pages to collect for each input. YouTube controls the page size. Results are saved after each page; collection stops when the list ends. Bootstrap requests do not count as result pages.

## Actor input object example

```json
{
  "inputList": [
    "https://www.youtube.com/playlist?list=PL2aBZuCeDwlRxnw-jDj51gmtBuCVZbsaZ"
  ],
  "pagesPerInput": 1
}
```

# Actor output Schema

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

Success and failed rows. Check the status column.

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

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

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

```

## MCP server setup

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