How to get all videos from a YouTube channel
Listing every upload on a channel sounds like one call. It is not. Search is rationed, the channel page loads videos as you scroll, and Shorts and live streams sit on separate tabs. Here are three methods that work, and the traps in each.
Method 1: the uploads playlist (official API)
Every channel has a hidden playlist with all its uploads. Google's docs describe contentDetails.relatedPlaylists.uploads as "the ID of the playlist that contains the channel's uploaded videos". Google
- Call
channels.listwithpart=contentDetailsandforHandle=@nameorid=UC.... Read the uploads playlist ID. - Call
playlistItems.liston that ID withmaxResults=50, and follownextPageTokenuntil it is gone. source - Batch the video IDs into
videos.listcalls withpart=statistics,contentDetailsfor views, likes and duration.
Each of these calls costs 1 unit. quota table A channel with 5,000 uploads is about 100 pages, plus the stats calls: a few hundred units out of 10,000 a day.
Do not use search for this. search.list has only 100 calls a day, and Google says results with a channelId and type=video are capped at 500 videos. source
import requests
KEY = "YOUR_GOOGLE_KEY"
API = "https://www.googleapis.com/youtube/v3/"
ch = requests.get(API + "channels", params={
"part": "contentDetails", "forHandle": "@veritasium", "key": KEY}).json()
uploads = ch["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"]
ids, token = [], None
while True:
r = requests.get(API + "playlistItems", params={
"part": "contentDetails", "playlistId": uploads,
"maxResults": 50, "pageToken": token, "key": KEY}).json()
ids += [i["contentDetails"]["videoId"] for i in r["items"]]
token = r.get("nextPageToken")
if not token:
break
print(len(ids), "videos")
Method 2: yt-dlp
For a one-off list, yt-dlp reads channel tabs directly:
yt-dlp --flat-playlist --print "%(id)s %(title)s" "https://www.youtube.com/@veritasium/videos"
Run it again with /shorts and /streams in place of /videos, because each tab is separate. Flat mode is quick but may skip some metadata. source
Method 3: a per-call API
Data APIs return the uploads with stats in each page, so there is no second stats call and no quota to watch. This is the simplest path from a server or an AI agent. The cost is one call per page, so a 5,000-video channel is a fixed, known number of calls you can budget before you start. Look for an API that splits Shorts and live streams into their own lists, so you do not have to classify them afterwards.
Which method to pick
| Situation | Method |
|---|---|
| One channel, one time, on your laptop | yt-dlp |
| A few channels a day, free, from a server | Uploads playlist on the Data API |
| Many channels, Shorts and lives split out, or an AI agent | A per-call API |
| Your own channel with private analytics | YouTube Studio or the YouTube Analytics API |
Keeping the list current
You rarely need to re-read a whole channel. After the first full pull:
- Store every video ID you have, with the date you first saw it.
- Each day, read the newest page of uploads and stop at the first ID you already have.
- Once a week, refresh stats for videos from the last 30 days, since that is when most views change.
- Once a month, refresh stats for everything, or only for the videos you report on.
This keeps a channel with thousands of videos to a handful of calls a day.
Columns worth keeping
Video ID, URL, title, publish date, duration in seconds, format (video, Short or live), views, likes, comments and the date you pulled the stats. The pull date matters: views are a moving number, and you cannot compare two snapshots without it.
Traps to check
- Shorts and lives. The uploads playlist mixes everything; the official API has no Shorts flag. source
- Members-only and private videos may appear as IDs with no public stats.
- Premieres and scheduled streams can carry a future date. Filter them before you compute averages.
- Counts drift. The channel's video count may not match your list exactly. Store the list, not just the count.
- Freshness. Google's policies require refreshing or deleting stored API data after 30 days. source
Doing it with ScrapeIO
The YouTube channel videos API returns uploads newest first with views, likes and comments. Use the channel Shorts API and the channel lives API for the other tabs. Each page is 1 credit; loop on data.cursor while data.has_more is true.
curl "https://scrapeio.com/v1/youtube/channel-videos?handle=@veritasium" -H "x-api-key: YOUR_KEY"
Sources
Checked on 8 November 2026 from each vendor's own pages. Prices and limits change; follow the links before you decide.
- https://developers.google.com/youtube/v3/docs/channels
- https://developers.google.com/youtube/v3/docs/playlistItems/list
- https://developers.google.com/youtube/v3/determine_quota_cost
- https://developers.google.com/youtube/v3/docs/search/list
- https://developers.google.com/youtube/v3/docs/videos
- https://github.com/yt-dlp/yt-dlp
- https://developers.google.com/youtube/terms/developer-policies
100 free credits, no card. Credits never expire.
Get API key