# YouTube Channel Scraper (`sedgelabs/youtube-channel-scraper`) Actor

Every video from any YouTube channel, newest, popular or oldest first, with the channel's subscribers, total views, country, joined date and links on every row. No login.

- **URL**: https://apify.com/sedgelabs/youtube-channel-scraper.md
- **Developed by:** [Sedge Labs](https://apify.com/sedgelabs) (community)
- **Security:** Limited permissions
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Channel Scraper

Get the videos, Shorts and live streams from any YouTube channel, sorted by latest, most popular or
oldest, with the channel's profile on every row: subscribers, total views, video count, country,
joined date, description and links. No login and no API key.

### What you get

One row per video, Short or stream:

- `type`: `video` from the channel's Videos tab, `short` from its Shorts tab, `stream` from its
  Live tab
- title, URL, video ID, length, thumbnail
- views as the channel shows them ("27M views") and the video's age ("3 weeks ago"), with an
  estimated publish date
- the channel's name, ID and handle
- `channel`: the channel's profile, the same on every row of that channel

Turn on **Exact details** for each video's exact views, likes, publish date and time, full
description, keywords and category. The actor then opens each video, one extra request each,
charged as a separate small event.

#### Shorts and live streams

The Videos tab comes by default. Set **Max Shorts per channel** or **Max live streams per channel**
above 0 to get those tabs as well, each up to its own limit, or set **Max videos per channel** to 0
to leave the Videos tab out.

- A Short comes with its rounded views and no date, because the Shorts tab shows none. Exact
  details give it a date.
- The Live tab lists upcoming streams ("7 waiting", no date yet), live ones (`isLive`, "114
  watching") and past ones ("Streamed 4 days ago"). With Exact details on, an upcoming stream's
  `publishedAt` comes before its start, so don't read it as the start time.

#### The channel profile

| Field | What it is |
|---|---|
| `url` | The channel's URL |
| `subscriberCount` | Rounded as YouTube shows it: 524M is 524,000,000 |
| `subscriberCountText` | As shown: "524M subscribers" |
| `videoCount` | Videos on the channel |
| `viewCount` | Total views of the channel, exact |
| `joinedAt` | The day the channel was created: "2012-02-19" |
| `country` | As YouTube names it: "United States" |
| `description` | The channel's description |
| `links` | The links on the channel, with the creator's labels and the real addresses |
| `isVerified` | A check mark, or an Official Artist Channel note, next to the name |
| `isArtist` | An Official Artist Channel |
| `avatarUrl`, `bannerUrl` | The channel's pictures |
| `keywords` | The channel's own keywords |

The business email on a channel's About page needs a signed-in YouTube account, so the actor
doesn't collect it.

### Profiles only

To get a list of channels with their profiles and no videos, turn on **Profiles only**. You get one
row per channel and the actor opens no video, Short or stream tab. **Max videos per channel** is
ignored. **Max Shorts**, **Max live streams**, **Exact details**, **Sort by** and **Videos from**
have nothing to apply to, so the run refuses them if you change them from their defaults.

```json
{
  "input": "@MrBeast",
  "type": "channel",
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "channelName": "MrBeast",
  "channelHandle": "@MrBeast",
  "url": "https://www.youtube.com/@MrBeast",
  "subscriberCount": 524000000,
  "subscriberCountText": "524M subscribers",
  "videoCount": 1011,
  "viewCount": 145347938308,
  "joinedAt": "2012-02-19",
  "country": "United States",
  "isVerified": true
}
```

The row has the fields listed under [The channel profile](#the-channel-profile), flat, next to the
channel's name, ID and handle, and shows in the Output tab's **Channel profiles** view. A channel
that can't be read gets the same free error row described below. If a channel's About panel can't
be read, its row still comes with the header's part (name, handle, subscribers, description,
keywords, pictures), the rest is empty, and the run summary says so. The status message counts the
profiles saved and the channels that failed, as in "3 channel profiles from 4 channels: 3 complete,
1 failed."

### Only new videos

Set **Videos from** to a date (`2026-01-31`) or an age (`30 days`) with sort set to Latest. The run
stops at the first older video, so you pay only for the ones in the window. Run it on a schedule to
track channels.

Without Exact details, the date comes from the age YouTube shows, which it rounds: "1 year ago"
can mean 12 to 23 months. The actor reads each age as the most recent date it allows, so a video
near your date is kept rather than lost, and a few videos just past it can come back. With Exact
details on, the limit uses each video's exact publish date.

The limit applies to each tab. Upcoming and live streams are always kept and never end the tab,
because their dates don't follow the tab's order. With Shorts in the run, a date limit needs Exact
details on, because the Shorts tab shows no dates.

### Input example

```json
{
  "channels": ["@MrBeast", "https://www.youtube.com/channel/UCTgwcoeGGKmZ3zzCXN2qo_A"],
  "maxVideosPerChannel": 50,
  "maxStreamsPerChannel": 10,
  "sortBy": "latest",
  "oldestDate": "30 days"
}
```

Channels can be handles, channel URLs or channel IDs, up to 1,000 per run.

### Output example

```json
{
  "input": "@MrBeast",
  "rank": 1,
  "type": "video",
  "videoId": "_c2e1NcI3Sc",
  "url": "https://www.youtube.com/watch?v=_c2e1NcI3Sc",
  "title": "Beat LeBron In Basketball, Win $100,000",
  "channelName": "MrBeast",
  "channelHandle": "@MrBeast",
  "viewCount": 27000000,
  "viewCountText": "27M views",
  "durationSeconds": 1348,
  "publishedTimeText": "17 hours ago",
  "publishedAtApprox": "2026-10-31T16:46:19.965Z",
  "hasExactDetails": false,
  "channel": {
    "url": "https://www.youtube.com/@MrBeast",
    "subscriberCount": 524000000,
    "subscriberCountText": "524M subscribers",
    "videoCount": 1011,
    "viewCount": 145347938308,
    "joinedAt": "2012-02-19",
    "country": "United States",
    "links": [{ "title": "Follow", "url": "https://www.instagram.com/mrbeast/" }],
    "isVerified": true,
    "isArtist": false
  }
}
```

The full row has more fields; see the Output tab.

### Channels that fail

A channel that returns nothing because something went wrong, such as a handle that doesn't exist,
gets one row of its own, free of charge:

```json
{
  "input": "@nosuchchannel",
  "type": "error",
  "error": "channel_not_found",
  "errorMessage": "@nosuchchannel: YouTube says this channel does not exist."
}
```

Filter on `type` to keep these rows apart from the videos. A channel that returned some rows gets
none, even if one of its tabs is missing; that tab's sentence is in `RUN_SUMMARY`.

### Pricing

$1.00 per 1,000 videos, plus $1.00 per 1,000 videos for exact details when you turn them on. Shorts
and live streams count as videos. Apify's platform usage and proxies are included. A channel that
doesn't exist, or a tab it doesn't have, costs nothing, and the rows for channels that fail are free.

YouTube declines the exact details for a few videos in every hundred. Those rows still arrive with
what the Videos tab shows, and their details charge is not applied.

With **Profiles only** on, each channel profile costs $0.003 ($3.00 per 1,000), with no video
charges. A profile whose About panel can't be read is still charged, since its row carries the
header's part.

### Why did a channel stop where it did?

Each channel gets one plain sentence per tab in `RUN_SUMMARY`:

- "50 videos for @MrBeast: stopped at your limit of 50."
- "12 videos for @MrBeast: stopped at the first one older than your date limit."
- "10 Shorts for @MrBeast: stopped at your limit of 10."
- "@MrBeast: This channel has no Live tab."
- "@somechannel: This channel has no Videos tab."

### FAQ

#### Do I need a YouTube account or proxies?

No. It reads public channel pages logged out and uses Apify's proxy by default.

#### Does it get Shorts and live streams?

Yes. Set **Max Shorts per channel** or **Max live streams per channel** above 0. For Shorts on
their own, [YouTube Shorts Scraper](https://apify.com/sedgelabs/youtube-shorts-scraper) has exact
details on by default.

#### Can I use it through the API, Make, Zapier or n8n?

Yes, like any Apify actor. Call it with your API token and read the dataset when the run finishes.

#### Is scraping YouTube channels legal?

The actor collects only public information, logged out. You are responsible for how you use it.
If you're unsure, ask a lawyer. Don't use the data for spam, impersonation or any other unlawful
purpose.

This actor is independent and not affiliated with, endorsed by or sponsored by YouTube or Google.
YouTube is a trademark of Google LLC.

### More from Sedge Labs

- [YouTube Comments Scraper](https://apify.com/sedgelabs/youtube-comments-scraper): comments and replies from any public video, Short or live replay.
- [YouTube Search Scraper](https://apify.com/sedgelabs/youtube-search-scraper): the videos and Shorts from any search, with YouTube's own filters.
- [YouTube Shorts Scraper](https://apify.com/sedgelabs/youtube-shorts-scraper): a channel's Shorts with exact views, likes and publish dates.

### Support

Open an issue on the Issues tab and include your run link.

# Actor input Schema

## `channels` (type: `array`):

Channel handles (@name), channel URLs or channel IDs (UC...). Up to 1,000 per run.

## `maxVideosPerChannel` (type: `integer`):

Stop after this many videos per channel. 0 leaves the Videos tab out.

## `maxShortsPerChannel` (type: `integer`):

Also get Shorts from the channel's Shorts tab, up to this many per channel. 0, the default, leaves them out.

## `maxStreamsPerChannel` (type: `integer`):

Also get streams from the channel's Live tab, up to this many per channel: past streams, live ones and upcoming ones. 0, the default, leaves them out. An upcoming stream has no date yet, and shows "7 waiting" where views would be.

## `sortBy` (type: `string`):

Each tab's own order, as on the channel's page.

## `includeDetails` (type: `boolean`):

Fetch each video's exact views, likes, publish date, description, keywords and category. The tabs alone show rounded views ("27M views") and an age ("3 weeks ago"), and the Shorts tab shows no date at all. One extra request per video, charged as a separate small event.

## `oldestDate` (type: `string`):

Only videos published on or after this: a date like 2026-01-31, or an age like "30 days". Stops at the first older video, so you don't pay for the rest. Needs Sort by Latest. Without Exact details the date comes from the rounded age YouTube shows ("1 year ago"), so a few videos just past your date can come back. With Shorts, it needs Exact details on, because the Shorts tab shows no dates.

## `profileOnly` (type: `boolean`):

Return one row per channel with its profile (name, handle, subscribers, video count, total views, joined date, country, links, description, keywords) and no videos. Max videos per channel is ignored. Max Shorts, Max live streams, Sort by, Exact details and Videos from are rejected if you change them from their defaults. Charged as its own event, once per channel.

## `proxyConfiguration` (type: `object`):

Proxy for the channel pages. Apify's datacenter proxy works for these. Exact details always go through Apify residential IPs at no extra proxy cost to you; YouTube refuses them from datacenter IPs.

## Actor input object example

```json
{
  "channels": [
    "@MrBeast"
  ],
  "maxVideosPerChannel": 10,
  "maxShortsPerChannel": 0,
  "maxStreamsPerChannel": 0,
  "sortBy": "latest",
  "includeDetails": false,
  "profileOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `videos` (type: `string`):

One row per video, with the channel's profile.

## `profiles` (type: `string`):

With Profiles only on: one row per channel with its profile and no videos.

## `summary` (type: `string`):

Per channel: how many videos you got and why it stopped.

# 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 = {
    "channels": [
        "@MrBeast"
    ],
    "maxVideosPerChannel": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("sedgelabs/youtube-channel-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 = {
    "channels": ["@MrBeast"],
    "maxVideosPerChannel": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("sedgelabs/youtube-channel-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 '{
  "channels": [
    "@MrBeast"
  ],
  "maxVideosPerChannel": 10
}' |
apify call sedgelabs/youtube-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sedgelabs/youtube-channel-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/JIPq9yIjlNUr1Yqwa/builds/pTh7xjadcxhk2BV8w/openapi.json
