YouTube Playlist Scraper - $0.40/1k, No API Key
Pricing
from $0.40 / 1,000 video returneds
YouTube Playlist Scraper - $0.40/1k, No API Key
Export every video in a YouTube playlist. Each row has id, title, watch URL, thumbnail, views, age and runtime. Views and age arrive as text, not numbers: "20M views", "6 years ago". Long playlists finish in one run. No Google API key. $0.40/1k.
Pricing
from $0.40 / 1,000 video returneds
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
10
Total users
2
Monthly active users
a day ago
Last modified
Categories
Share
YouTube Playlist Scraper: every video in a playlist, as rows
Paste playlist links or bare PL and UU ids and you get one row per video: id, title, watch link,
uploader, view count, age, runtime and the largest thumbnail YouTube offers. It keeps paging, so a
long playlist comes back in one run rather than stopping at the first twenty.
The thing that catches people out: channelName is read off each video's own byline, not off the
playlist. A playlist collecting clips from nineteen creators gives you nineteen different channels,
which is usually what you want and occasionally not.
| Input | Playlist links, or bare PL, UU, OL, RD, FL, LL ids |
| Output | One row per video |
| Ceiling | 5,000 videos per run |
| Account needed | None from you |
| Price | $0.40 per 1,000 videos, flat on every plan |
🗂️ What YouTube Playlist Scraper does
Anything with ?list= in it works, including a plain watch link that happens to carry a playlist
parameter. Bare ids work too, and so does a Mix. No Google API key, no OAuth screen, no daily quota.
It follows the playlist's own continuations, up to 80 pages per playlist, which is a very long list
before it matters. maxItems is the budget for the whole run, not per playlist, so it is also
your spend cap.
Videos are deduplicated by videoId across every playlist in the run. A video sitting in two of your
playlists is returned once and billed once.
📥 What you give it
{"playlistUrls": ["https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf"],"maxItems": 100}
| Field | Default | What it is |
|---|---|---|
playlistUrls | none | Any link containing ?list=. A watch link with a list parameter counts. |
playlistIds | none | Or bare ids: PL, UU, OL, RD, FL, LL. |
maxItems | 100 | Total videos across every playlist in the run, 1 to 5,000. This is also your spend cap. |
notionConnector, notionParentId | none | Optional. Write each video into a Notion database as well as the dataset. |
proxyConfiguration | Apify default | Leave it alone unless you have your own servers you want the run to go out through. |
Send at least one of playlistUrls or playlistIds. With neither, the run fails rather than
returning a polite row.
📤 What you get back
A real row from a real run, with the thumbnail link cut short:
{"ok": true,"videoId": "0VH1Lim8gL8","title": "Deep Learning State of the Art (2020)","url": "https://www.youtube.com/watch?v=0VH1Lim8gL8","channelName": "Lex Fridman","channelId": "UCSHZKyawb77ixDdsGog4iWA","viewCountText": "1.3M views","publishedTimeText": "6 years ago","lengthText": "1:27:41","thumbnail": "https://i.ytimg.com/vi/0VH1Lim8gL8/hqdefault.jpg?sqp=...","mode": "playlist"}
| Field | What it is |
|---|---|
videoId, url | The 11 character id and the canonical watch link. Use videoId as your key across runs. |
channelName, channelId | The video's own uploader, read off its byline. Roughly one row in a hundred arrives with no byline and these two come back blank. |
viewCountText | "1.3M views", as the playlist page renders it. |
publishedTimeText | "6 years ago". Relative to when the run read the page. |
lengthText | "1:27:41". Empty on a live stream or a premiere. |
thumbnail | The largest one YouTube offers for that video. |
mode | Always playlist here, so rows merge cleanly with the other YouTube scrapers. |
The counts and dates are strings, not numbers. "1.3M views" is what the page prints, and the
exact figure is not in it. If you need integers and real dates, parse what you can and accept the
rounding.
🧾 Reading the output
Two kinds of row land in your dataset.
| Row | How to spot it | Billed |
|---|---|---|
| A video | ok: true | yes |
| A diagnostic | ok: false and an errorCode | no |
Filter on ok == true and you have your data. A playlist that fails gets its own uncharged
diagnostic row naming the playlistId and the reason, and the run carries on to the next one.
NO_RESULTS means the run finished with nothing to show, BLOCKED and RATE_LIMITED mean YouTube
pushed back on the request, SERVER_ERROR is a 5xx and NETWORK means it could not be reached.
One quirk of the Overview table: it shows the video columns only, so a diagnostic row reads as a
blank line there. Open the row or download the JSON to see the errorCode.
▶️ How to run it
- Open YouTube Playlist Scraper and click Try for free.
- Paste links into Playlist URLs, or ids into Playlist IDs.
- Set Max videos. Start at 100 while you look at the shape.
- Click Start.
- Download the dataset as JSON, CSV or Excel, or read it over the Apify API.
💰 How much does it cost?
$0.40 per 1,000 videos. Flat on every Apify plan, no volume tiers.
You pay per video row delivered. Diagnostic rows and duplicates inside a run are never billed, so a
playlist that returns nothing delivers no charged rows. maxItems is the ceiling on both the rows
and the spend.
💡 What people use it for
- Turning a course or conference playlist into a spreadsheet, then working down it.
- Pulling a channel's uploads playlist as a single ordered list.
- Collecting video ids from a curated playlist to feed the transcript or comments actors.
- Auditing a playlist you inherited, to see which creators are actually in it.
🚧 What it does not do
- Public and unlisted playlists only. A private playlist needs a signed-in account and will not work here.
- No exact view counts and no real dates. The strings are what the page carries.
- No descriptions, likes, comments or transcripts. Those are separate actors, two linked below.
- Paging stops at 80 pages per playlist. That is a very long list, but it is the ceiling.
- The playlist's own title and owner are not returned. Rows describe videos, not the playlist.
- Order is the playlist's order, and there is no sort option.
- Nothing valid in the input fails the run rather than returning an explanatory row.
🧭 Which YouTube scraper do you need?
| If you want | Use |
|---|---|
| Every video in a playlist | This one |
| A channel's uploads, without finding its playlist id | YouTube Channel Scraper |
| Keyword search results | YouTube Scraper |
| The spoken words in each video | YouTube Transcript Scraper |
| The videos themselves as files | YouTube Downloader |
❓ Questions people ask
Do I need a YouTube or Google account? No. Nothing here is signed in, and there is no quota.
Is maxItems per playlist? No, it is the total for the run. Five playlists at 100 gives you 100
rows altogether, not 500.
Why does channelName differ row to row? Because it is the video's uploader, not the playlist's
owner. On a channel's own uploads playlist they are the same thing.
Can I get a channel's videos without knowing its playlist id? Yes, use the channel scraper linked above.
Is scraping YouTube legal? This reads public and unlisted playlist pages, nothing signed in. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
Can I run it on a schedule? Yes. Apify's scheduler, or start it from the API and read the dataset when it finishes.
🆘 If something breaks
Open the Issues tab on the actor page. Include the playlist link or id you used and the run ID, and the log is enough for us to see what happened.