YouTube Channel Videos Scraper: a channel’s uploads

YouTube Channel Videos Scraper takes a channel and returns its videos, each with numeric views and likes, the full description and keyword list, and the streaming formats YouTube would serve to a player.

apidojo/youtube-channel-scraper
Input method

Estimated run cost

$0.00

Free Apify plan: 5 runs a month, 10 items a run. No credit card.

$0.015
per channel queried
~30
videos, or ~48 Shorts, included
$0.0005
per video after
99.81%
run success, last 30 days

Read on 27 September 2026.

Name the channel, or go looking for one

Same eight fields as the Channel Scraper, different prices on all of them. A channel query is the expensive one and the one that actually returns videos; a keyword search returns channels and costs five times what the same search costs on the sibling actor.

  • startUrls

    $0.015per channel

    ~30 videos in

    Channel URLs. The main door. This is what triggers the $0.015 channel query that returns uploads.

    https://www.youtube.com/@ThreeDaysGraceVEVO

  • youtubeHandles

    $0.015per channel

    ~48 if Shorts

    The @handle form, when you would rather store handles than URLs. Billed the same as a channel URL.

    ["@MrBeast"]

  • Do your searching on the other actor

    keywords

    $0.005per search

    ~20 channels in

    A term to search channels with. Cheaper than a channel query but five times what the Channel Scraper charges for it.

    ["acoustic covers"]

  • gl / hl / sort

    us / en / rthe defaults

    Search only

    Country, language, and ordering. The schema notes sort works only with search keywords.

    sort: "r"

maxItems and the "maximum charged results" field work together, and the listing warns that leaving both empty produces infinite results, which against a channel with ten thousand uploads is a five-dollar run you did not intend.

YouTube Channel Videos Scraper specificationsapidojo/youtube-channel-scraper
Apify actorapidojo/youtube-channel-scraper
InputsstartUrls · youtubeHandles · keywords · gl · hl · sort · maxItems · customMapFunction
ReturnsVideo records, each with a streamingData block of playable formats
EngagementNumbers, not strings, views 276328963, likes 1796037
DurationPlain seconds as an integer
Free pageAbout 30 videos, or about 48 Shorts, it varies by content type
Keyword search$0.005 here, $0.001 on the Channel Scraper for the same thing
Reliability99.81% of 531 runs succeeded in the last 30 days

One catalogue, a set of channels, or the files themselves

Three runs. The third is not a different input. It is the same run read differently, because the streaming block is already in every record you have paid for.

How do you scrape all videos from a YouTube channel?

Give the channel URL. The query costs $0.015 and includes roughly the first thirty videos; everything after is $0.0005. A hundred videos from one channel comes to $0.05.

Input

{
  "startUrls": ["https://www.youtube.com/@ThreeDaysGraceVEVO"],
  "maxItems": 100
}

$0.015 + 70 × $0.0005=$0.05

What comes back

The video record, Integers where they should be integers, and seconds for duration.

{
  "id": "lL2ZwXj1tXM",
  "title": "Three Days Grace - Never Too Late",
  "status": "OK",
  "url": "https://www.youtube.com/watch?v=lL2ZwXj1tXM",
  "duration": 211,
  "views": 276328963,
  "likes": 1796037,
  "isLive": false,
  "isPrivate": false
}

A page of Shorts is bigger than a page of videos

The listing prices the free first page as "~48 shorts or ~30 videos". The same $0.015 therefore stretches further on a Shorts-heavy channel, and a budget built on the thirty figure will simply come in under on one.

How do you compare several YouTube channels?

List them together. Each channel brings its own free page, so five channels sharing five hundred videos costs $0.25, identical to taking five hundred from one channel, because the extra query fees and the extra allowances cancel out.

Input

{
  "youtubeHandles": ["@MrBeast", "@ThreeDaysGraceVEVO"],
  "maxItems": 500
}

5 × $0.015 + 350 × $0.0005=$0.25

What comes back

The channel block, Three fields naming the uploader, so a mixed run sorts itself.

{
  "channel": {
    "id": "UCK-VRwguZP3cokOAxI0F1HA",
    "name": "ThreeDaysGraceVEVO",
    "url": "https://www.youtube.com/channel/UCK-VRwguZP3cokOAxI0F1HA"
  },
  "keywords": ["three days grace", "rock", "official video"]
}

Five channels and one channel cost the same for the same videos

At five hundred videos the two runs are both $0.25. The arithmetic only diverges at depth: past a few hundred per channel the item rate dominates and the free pages stop mattering, so spread the run wide while it is still cheap to do so.

Can you get the actual video file URLs?

They are already there. Every record carries a streamingData block with formats and adaptiveFormats, direct URLs, codecs, bitrates and audio channels, so the download links come with the metadata rather than costing anything extra.

Input

{
  "startUrls": ["https://www.youtube.com/@ThreeDaysGraceVEVO"],
  "maxItems": 30
}

1 × $0.015=$0.015

What comes back

The streamingData, One entry per available rendition, video and audio separately.

{
  "streamingData": {
    "adaptiveFormats": [
      {
        "itag": 140,
        "mimeType": "audio/mp4; codecs=\"mp4a.40.2\"",
        "bitrate": 130517,
        "audioQuality": "AUDIO_QUALITY_MEDIUM",
        "audioSampleRate": "44100",
        "audioChannels": 2,
        "contentLength": "3418563"
      }
    ]
  }
}

Stream URLs are signed and expire

The URLs in the sample carry an expire parameter and a signature. They are usable immediately and not later, so a record stored for a week keeps its metadata and loses its links, re-run for fresh ones rather than building an archive on them.

A video, and the file behind it

Four blocks, and one of them is far larger than the rest. streamingData routinely dwarfs everything else in a record, which matters when you are deciding what to keep.

  • 8

    The video

    Top level

    • id, title, url
    • status, "OK" on a healthy record
    • description, full, untruncated
    • duration, seconds, integer
    • isLive, isPrivate
  • 2

    Engagement

    Real numbers

    • views, 276328963
    • likes, 1796037
    • No parsing required
  • 3

    The uploader

    channel

    • id, UC format
    • name
    • url
  • 2

    Media

    The bulky part

    • thumbnails, sizes from 120px up
    • streamingData.formats
    • streamingData.adaptiveFormats
Field referenceDocumented in the actor README
id · url · titleVideo ID, watch URL and title
statusRecord status, "OK" in the listing’s sample
descriptionThe full description, links and all. Often the longest field in the row
durationLength in seconds as an integer, no parsing, no ISO 8601 duration string
views · likesIntegers. Compare and sum them directly, unlike the Comments actor’s strings
keywordsArray of the video’s own tags, thirty of them in the listing’s sample
isLive · isPrivateBooleans worth filtering on before any engagement analysis
channel.id · name · urlWho uploaded it. The ID is the key to carry between actors
thumbnailsArray of sizes, each with url, width and height
streamingData.formatsCombined audio-and-video renditions
streamingData.adaptiveFormatsSeparate video and audio streams, what a player actually selects between
itag · mimeType · qualityLabelPer-format identifiers and codecs, e.g. "144p" or audio/mp4
bitrate · averageBitrate · contentLengthSize and rate, enough to pick a rendition before fetching it
audioQuality · audioSampleRate · audioChannelsAudio characteristics per stream, e.g. 44100 Hz, 2 channels
approxDurationMsPer-stream duration in milliseconds, as a string

adaptiveFormats is where a player looks and where you should too: it separates video from audio, so a job that only needs the soundtrack can take a three-megabyte audio stream instead of the full file.

Before you run it against a big channel

Three from the listing’s own pricing and troubleshooting, and two that follow from what the output actually contains.

  • 01

    Both ceilings default to unlimited

    The troubleshooting section names maxItems alongside "maximum charged results" and warns that leaving both empty results in infinite results. Against a ten-thousand-upload channel that is a five-dollar run.

  • 02

    The free page is not a fixed number

    It is roughly 48 Shorts or roughly 30 videos. Budget on thirty and treat anything more as a discount rather than planning around the higher figure.

  • 03

    Search here costs five times what it costs next door

    A keyword search is $0.005 on this actor and $0.001 on the Channel Scraper, both including about twenty channels. Find channels there, pull uploads here.

  • 04

    Stream URLs are short-lived

    The googlevideo links carry expiry timestamps and signatures. Treat them as fetch-now, not as archival references.

  • 05

    Records are large

    streamingData carries an entry per rendition with codecs, byte ranges and URLs. If you only need engagement, strip it with customMapFunction, which the listing permits for transformation but bans for filtering.

Free accounts run in demo mode: 5 runs a month, 10 items each.

Where the channel fee stops mattering

Six scenarios from the listing, all reproducing from the three charge events. The channel query is the largest single fee in the YouTube family, and it stops being the dominant part of a bill at about a hundred videos.

What a run costsQuery fee + $0.0005 × billable items
RunMethodCalculationCost
20 channels1 keyword search$0.005$0.005
30 videos1 channel, the free page$0.015$0.015
100 videos1 channel$0.015 + 70 × $0.0005$0.05
500 videos1 channel$0.015 + 470 × $0.0005$0.25
500 videos5 channels5 × $0.015 + 350 × $0.0005$0.25
1,000 videos10 channels10 × $0.015 + 700 × $0.0005$0.50

The fourth and fifth rows are the same price for the same videos, which is the clearest signal in this pricing: below a few hundred videos per channel, spreading a run across more channels is free. Above it, the item rate takes over and the allowances stop helping.

Who needs the uploads themselves?

The listing points at influencer analysis and lead generation, but the streaming block widens that considerably, anyone who needs the media and not just the metrics is here rather than on the channel or comments actors.

  • Content analysis

    One catalogue, deep

    Read a channel’s entire output with numeric views and likes that need no parsing before comparison

    $0.25 per 500 videos

  • Competitive benchmarking

    A set of channels

    Compare cadence and performance across five channels for the price of pulling one

    $0.25 across 5 channels

  • Media and archival work

    The files

    Take the streaming formats to fetch renditions directly, choosing bitrate and codec before downloading

    $0.015 per channel page

  • Transcription pipelines

    The files, audio only

    Pull the audio-only adaptiveFormat rather than the full video, then hand it to a speech model

    $0.05 per 100 videos

  • SEO and tag research

    One catalogue

    Mine the keywords array across a channel’s uploads to see how it actually tags itself

    $0.50 per 1,000 videos

Taking what you need and dropping the rest

The actor is apidojo/youtube-channel-scraper. Because streamingData dominates the payload, the first decision is whether you want it, and if you do, use it quickly.

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("apidojo/youtube-channel-scraper").call(run_input={
    "startUrls": ["https://www.youtube.com/@ThreeDaysGraceVEVO"],
    "maxItems": 100,      # never leave this empty on a large channel
})

videos = list(client.dataset(run.default_dataset_id).iterate_items())

# views and likes are integers here: no parsing, unlike the comments actor.
live_excluded = [v for v in videos if not v["isLive"] and not v["isPrivate"]]
best = sorted(live_excluded, key=lambda v: v["likes"] / max(v["views"], 1), reverse=True)

for v in best[:10]:
    rate = v["likes"] / v["views"] * 100
    print(f"{rate:.2f}%  {v['duration']:>5}s  {v['title'][:50]}")

# Audio-only renditions are a fraction of the size of the full file.
def audio_stream(v):
    fmts = v.get("streamingData", {}).get("adaptiveFormats", [])
    return next((f for f in fmts if f.get("mimeType", "").startswith("audio/")), None)
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('apidojo/youtube-channel-scraper').call({
  youtubeHandles: ['@MrBeast', '@ThreeDaysGraceVEVO'],
  maxItems: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();

// channel.id keeps a multi-channel run sorted.
for (const [id, vids] of Object.entries(Object.groupBy(items, (v) => v.channel.id))) {
  const views = vids.reduce((n, v) => n + v.views, 0);
  const mins = Math.round(vids.reduce((n, v) => n + v.duration, 0) / 60);
  console.log(vids[0].channel.name, vids.length, 'videos', views.toLocaleString(), 'views', mins, 'min');
}

// Stream URLs expire, fetch now or re-run later, do not archive the link.
const smallest = items[0]?.streamingData?.adaptiveFormats
  ?.filter((f) => f.contentLength)
 .sort((a, b) => Number(a.contentLength) - Number(b.contentLength))[0];
console.log('smallest rendition:', smallest?.mimeType, smallest?.contentLength);
curl -X POST \
  "https://api.apify.com/v2/acts/apidojo~youtube-channel-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":["https://www.youtube.com/@ThreeDaysGraceVEVO"],"maxItems":30}'

Export as JSON, CSV will flatten the streaming and thumbnail arrays into something unusable. If the streams are not needed, strip them in customMapFunction and the payload shrinks by an order of magnitude.

YouTube Channel Videos Scraper FAQ

How much does it cost to scrape a YouTube channel’s videos?

$0.015 for the channel query, which includes roughly the first 30 videos or 48 Shorts, then $0.0005 per video. A hundred videos is $0.05 and five hundred is $0.25.

Does it return video download links?

Every record carries a streamingData block with formats and adaptiveFormats, direct URLs, codecs, bitrates and audio channels. The links are signed and expire, so use them promptly rather than storing them.

Are views and likes numbers?

Yes, integers, 276328963 views and 1796037 likes in the listing’s sample, with duration in plain seconds. That differs from the YouTube Comments Scraper, which returns counts as strings like "3.4K".

Why is the free allowance different for Shorts?

The listing prices the included first page as about 48 Shorts or about 30 videos, because a page of Shorts holds more. The same $0.015 therefore stretches further on a Shorts-heavy channel.

How is this different from the Channel Scraper?

That one returns the channels themselves, subscriber counts, descriptions, verification. This one returns their uploads. A keyword search also costs $0.005 here against $0.001 there.

Can I search for channels with this actor?

You can, at $0.005 a search with about twenty channels included, but the same search is a tenth of a cent on the Channel Scraper, so discovery is cheaper there.

What happens if I leave maxItems empty?

The listing warns that leaving maxItems and "maximum charged results" both empty produces infinite results. On a channel with thousands of uploads that is a multi-dollar run.

Can I get just the audio?

Pick the audio-only entry out of streamingData.adaptiveFormats. It carries its own contentLength, sample rate and channel count, and is a fraction of the size of the full video.

Where YouTube Channel Videos Scraper fits

Pull one catalogue

A cent and a half, thirty videos in, streams included.

startUrls: [one channel URL] · maxItems: 30

Run this scraper free

Apidojo is not affiliated with YouTube or Google LLC.