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

List every video, Short or live stream on a YouTube channel. Accepts handles like @mkbhd, channel URLs, or raw channel IDs and resolves them for you. Returns video ID, title, view count, duration, publish time and thumbnail, paginated as deep as you need, with no API key or quota.

- **URL**: https://apify.com/superslowsloth/youtube-channel-scraper.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** Videos, Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## YouTube Channel Videos Scraper

Lists what a YouTube channel has published. Give it channels and it returns one
row per video, with the title, view count, publish date, duration, thumbnail and
live status exactly as the channel page shows them.

No API key, no quota, and no login is involved: the actor reads YouTube's own
public browse endpoint, the same one the website calls.

### Input

| Field | Type | Notes |
|---|---|---|
| `channels` | array | Required. Handles (`@mkbhd`), channel URLs (`youtube.com/@mkbhd`, `youtube.com/c/LinusTechTips`, `youtube.com/user/marquesbrownlee`, `youtube.com/channel/UC...`) and bare channel IDs (`UC...`) are all accepted, mixed freely. |
| `tab` | string | `videos` (default), `shorts`, or `live`. |
| `maxResults` | integer | Videos per channel, default 50. Pages hold about 30 items, so larger numbers simply fetch more pages. |
| `proxyConfiguration` | object | Recommended. YouTube answers datacenter addresses with a bot check. |

Handles and custom URLs are turned into a channel ID through YouTube's
`navigation/resolve_url` endpoint before anything is listed, so a run costs one
extra request per non-ID input and nothing after that.

### Output

One dataset item per video:

```json
{
  "channel_id": "UCXuqSBlHAE6Xw-yeJA0Tunw",
  "tab": "videos",
  "video_id": "DXK-F0SjC_E",
  "url": "https://www.youtube.com/watch?v=DXK-F0SjC_E",
  "title": "I put the NEWEST CPU in the OLDEST Motherboard",
  "view_count_text": "721K views",
  "view_count": 721000,
  "concurrent_viewers_text": null,
  "published_time_text": "1 day ago",
  "scheduled_text": null,
  "duration_text": "13:48",
  "duration_seconds": 828,
  "thumbnail_url": "https://i.ytimg.com/vi/DXK-F0SjC_E/hq720.jpg",
  "is_live": false,
  "is_upcoming": false
}
```

### What the source does not give, and is therefore `null`

A channel tab is a listing page, not a video page. Missing values are `null`,
never `0` and never an empty string, because a zero reads as a measurement.

- **Exact view counts.** The tab shows `721K views`. `view_count_text` carries
  that string unchanged; `view_count` carries YouTube's own rounded figure
  (721000). It is not an exact count, and no exact count is available here.
- **Absolute publish dates.** Only relative text (`1 day ago`,
  `Streamed 1 month ago`) is provided. Nothing is converted to a timestamp,
  because "1 month ago" cannot be turned into a date without inventing one.
- **Shorts have no duration and no publish date.** The Shorts tab carries the
  title and view count only, so `duration_text`, `duration_seconds` and
  `published_time_text` are `null` for every Short.
- **Live items have no view count.** While a stream is running the tab shows
  `12K watching` instead, which is in `concurrent_viewers_text`; `view_count`
  stays `null` because watchers are not views.
- **Upcoming items** carry `scheduled_text` (`Scheduled for 8/25/26, 4:00 AM`)
  and `is_upcoming: true`, with no view count and no duration.
- **Descriptions, tags, likes and comment counts** are not on the tab at all and
  are not returned.

### Reliability

YouTube refuses datacenter addresses with a bot check. Those refusals, along
with HTTP 403, 429 and 5xx, are treated as temporary: the actor rotates to a new
proxy address and retries. A channel that genuinely does not exist returns an
error alert and is reported once, without retries, so a typo costs one request
rather than a run's budget.

### Pricing

Pay per event. One charge per video delivered to the dataset, after it has been
pushed, and a small actor-start charge per run. Videos repeated across pages are
de-duplicated before charging, so no video is ever paid for twice in a run.

# Actor input Schema

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

One entry per channel. Handles (@mkbhd), channel URLs (youtube.com/@mkbhd, youtube.com/c/LinusTechTips, youtube.com/user/marquesbrownlee, youtube.com/channel/UC...) and bare channel IDs (UC...) are all accepted, mixed freely.

## `tab` (type: `string`):

Which tab to list: long-form Videos, Shorts, or Live streams and premieres. Shorts carry no duration or publish date, because the tab does not provide them.

## `maxResults` (type: `integer`):

Stop after this many videos from each channel. Pages are 30 items, so a larger number simply fetches more pages until the tab runs out.

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

Recommended. YouTube answers datacenter addresses with a bot check; residential addresses are served normally.

## Actor input object example

```json
{
  "channels": [
    "@mkbhd"
  ],
  "tab": "videos",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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": [
        "@mkbhd"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/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": ["@mkbhd"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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