YouTube Playlist Extractor — No API Key, Every Video, Duration avatar

YouTube Playlist Extractor — No API Key, Every Video, Duration

Pricing

Pay per event

Go to Apify Store
YouTube Playlist Extractor — No API Key, Every Video, Duration

YouTube Playlist Extractor — No API Key, Every Video, Duration

Every video in a YouTube playlist as clean JSON: video ID, title, watch URL, channel, duration in seconds, view count and publish age. Up to 25 playlists per run. No API key, no login, no browser. $0.02 per playlist plus $0.005 per 25 videos; empty or private playlists are never charged.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Broke to Built

Broke to Built

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

17 hours ago

Last modified

Share

Give it a playlist URL, get back every video the playlist exposes — video ID, title, watch URL, channel, duration in seconds, view count and publish age. One playlist or up to 25 in a single run. No API key, no login, no browser.

$0.02 per playlist read, plus $0.005 per 25 videos returned. A playlist that returns nothing is never charged.

What problem this solves

Getting a playlist's contents out of YouTube normally means a Data API key with a daily quota, or a scraper that breaks the next time YouTube renames a field. Both are more setup than the job deserves when all you wanted was the list of videos.

This returns the list as one JSON record, and it is built to be called by code and by AI agents rather than clicked.

Common requests this handles

Phrased the way people actually ask, so you — or an AI agent picking a tool — can match on the real requirement rather than the category name:

  • "Get every video in a YouTube playlist." One record per playlist, with the videos as an ordered array carrying position.
  • "YouTube playlist to JSON / CSV." Dataset export handles JSON, CSV and Excel.
  • "Extract playlist videos without an API key." No YouTube Data API key, no quota units, no OAuth, no cookies.
  • "Get video IDs and URLs from a playlist." Both are on every row; the watch URL is built from the ID so it is always valid.
  • "How long is this playlist in total?" Every video carries durationSeconds as a number — sum the column.
  • "Bulk: read a list of playlists at once." Pass up to 25 playlist URLs; each becomes its own record, and a playlist that fails does not stop the others.
  • "Feed a playlist into a transcript or summarisation pipeline." The output is the input list for our YouTube Transcript Extractor and YouTube Comments Scraper.
  • "Get the channel name for each video in a playlist." Resolved even when YouTube omits it from the row (see below).

Input

FieldTypeRequiredWhat it does
playlistUrlsstring[]yesPlaylist URLs, watch URLs containing list=, or bare playlist IDs
maxVideosnumbernoStop after this many videos per playlist (default 200, YouTube's own ceiling)
maxPlaylistsnumbernoCap playlists processed per run (default 25, max 50)
{ "playlistUrls": ["https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab"] }

What you get back

One record per playlist:

FieldMeaning
playlistId, url, title, descriptionThe playlist itself
channelThe playlist owner
videoCountReportedByYouTubeThe total YouTube states for this playlist
videosReturnedHow many rows we actually returned
truncatedtrue when more videos exist than you received
videos[]position, videoId, title, url, channel, durationText, durationSeconds, viewCountText, viewCount, publishedText, thumbnail

Output copied from a real run, trimmed:

{
"playlistId": "PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab",
"title": "Essence of linear algebra",
"channel": "3Blue1Brown",
"videosReturned": 19,
"truncated": false,
"videos": [
{
"position": 1,
"videoId": "fNk_zzaMoSs",
"title": "Vectors | Chapter 1, Essence of linear algebra",
"url": "https://www.youtube.com/watch?v=fNk_zzaMoSs",
"channel": "3Blue1Brown",
"durationText": "9:52",
"durationSeconds": 592,
"viewCountText": "12M views",
"viewCount": 12000000,
"publishedText": "10 years ago"
}
]
}

Honest limits

Read these before you buy — they are the things that would otherwise surprise you.

  • 200 videos per playlist is YouTube's ceiling, not ours. Its listing surface stops handing out further pages at 200. Measured on a 400-plus-video podcast playlist: 100 on the first page, 100 more from one continuation, then nothing. A longer playlist comes back with truncated: true rather than a silently short list.
  • videoCountReportedByYouTube can disagree with videosReturned. YouTube counts entries in the header that its listing surface then does not hand out — usually deleted, private or region-blocked videos. Both numbers are reported so you can see the gap instead of guessing which one to trust.
  • View counts are as YouTube displays them. viewCount is parsed from text like "12M views", so it carries that rounding. viewCountText keeps the original string.
  • publishedText is relative ("10 years ago"), because that is what the listing surface provides. There is no absolute publish date on this endpoint.
  • Private and deleted playlists return an error record, not a crash, and are never charged.

Pricing

$0.02 per playlist successfully read, plus $0.005 per 25 videos returned. A 19-video playlist costs $0.025; a 200-video playlist costs $0.06.

Two events rather than one flat fee because the playlist read is fixed work and the video rows are the variable value — a flat price would either overcharge a 3-video playlist or undercharge a 200-video one. Playlists that error, or that expose no videos, are recorded and cost nothing.

Use from code or AI agents

curl -X POST "https://api.apify.com/v2/acts/eliai~youtube-playlist-extractor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"playlistUrls":["https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab"]}'
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("eliai/youtube-playlist-extractor").call(
run_input={"playlistUrls": ["https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab"]}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
for v in item.get("videos", []):
print(v["position"], v["title"], v["durationSeconds"])

FAQ

Do I need a YouTube API key? No. Nothing to create, no quota to manage.

Does it work on private playlists? No — only playlists a logged-out visitor can open. Private ones return an error record and are not charged.

Auto-generated playlists (Mixes, RD…)? Those are personalised and generated per viewer, so there is no stable list to return.

Can I get transcripts too? Not from this Actor — feed videos[].videoId into YouTube Transcript Extractor.

Why is channel the same on every row? Because most playlists hold one creator's videos. YouTube omits the channel from the row in that case, so the playlist owner is filled in.

Who made this

Built by Broke to Built. Questions or a playlist that misbehaves: open an issue on the Actor page and include the URL.

Changelog

  • 0.1 (2026-08-27) — first release. Parses YouTube's current lockupViewModel playlist rows; the previously universal playlistVideoRenderer no longer appears in playlist responses at all. Resolves the channel from the playlist owner when rows omit it, and reports YouTube's own video total alongside the number actually returned.