# YouTube Channel Videos & Shorts Scraper (`datafabrik/youtube-channel-videos`) Actor

List every video, Short and live stream of YouTube channels: title, views, upload time, duration, thumbnail, plus subscribers and handle of each channel. Newest, most popular or oldest first. Paste @handles or links. No browser, no API key.

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

## Pricing

from $0.40 / 1,000 channel videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### What is YouTube Channel Videos & Shorts Scraper?

List **every video, Short and live stream of YouTube channels** as clean JSON, CSV or Excel: **title, link, views, upload time, duration and thumbnail** of each video, plus the **channel's name, handle, subscribers and video count**. Newest, most popular or oldest first, like the sort buttons on YouTube.

- 💲 **Pay per video**: from **$0.40 per 1,000 videos** ($0.70 on the Free plan), plus Apify's minimum start fee of $0.00005 per run. Channels not found, missing tabs and failures are **free**.
- 📺 **Videos, Shorts and Live tabs**, separately, for up to 1,000 channels per run and up to 10,000 videos per tab.
- 🔃 **Latest, Popular or Oldest first**: YouTube's own sort buttons.
- 🔗 **Paste what you have**: `@handle`, channel links, `/channel/UC…`, `/c/…`, `/user/…` or bare `UC…` ids.
- ⚡ **No browser, no YouTube API key, no login, no quota**: light HTTP requests, five channel tabs at a time.

### What data can you extract from a YouTube channel?

| Field | Example |
|---|---|
| Video title, link, id | Turning raw hardware sensor data into music with Gemini |
| Type | video, short, stream (past live), live, upcoming |
| Views (number and text) | 9700 · "9.7K views" |
| Upload time | "21 hours ago", "Streamed 4 months ago" |
| Duration | "1:27" · 87 s |
| Thumbnail | https://i.ytimg.com/vi/… |
| Rank in the tab | 1 |
| Channel name, id, handle, link, check-mark badge | Google for Developers, @GoogleDevelopers, ✔ |
| Subscribers (number and text) | 2680000 · "2.68M subscribers" |
| Channel video count | "6.1K videos" |

### What can you do with YouTube channel data?

- **Competitor watch**: list what your competitors upload, how often, and what gets the most views (**Order: Most popular first**).
- **Influencer research**: compare the subscribers and recent views of hundreds of channels in one run.
- **Content planning**: find the best-performing videos and Shorts of a niche to plan yours.
- **Monitoring**: schedule a daily run with **Max videos per tab: 10** to catch every new upload.
- **AI and research datasets**: collect the video links of a channel, then get their transcripts with our [YouTube Transcript Scraper](https://apify.com/datafabrik/youtube-transcripts), or find videos by keyword with our [YouTube Search Scraper](https://apify.com/datafabrik/youtube-search).

### Why run it on Apify?

- **API**: every run is an API call, with ready clients for Python and JavaScript (see below).
- **Scheduling**: check your channels every hour, day or week without a server.
- **Integrations**: Google Sheets, Slack, Zapier, Make, n8n, webhooks and your own database.
- **AI agents**: available through Apify's MCP server, so Claude, ChatGPT or Cursor can call it.

### How does it work?

1. Each entry of `channels` is recognised (handle, link or id); handles are turned into channel ids.
2. For each channel, the Actor opens each tab of `tabs` (Videos, Shorts, Live), clicks the sort button of `sortBy` when it is not "Latest", and reads the pages one after the other, like scrolling down, until it has `maxResultsPerTab` videos or the tab ends.
3. Each video becomes one item with its `position` in the tab and the channel's details. Only `ok` items are charged.
4. A channel that does not exist, a tab the channel does not have (no Shorts, no Live), an empty tab or a failure leaves one free item with `status` and `note`, so nothing disappears silently.

### How to scrape the videos of a YouTube channel

1. Click **Try for free**.
2. Paste one or more channels in **Channels**, one per line.
3. Optional: pick the **Tabs**, the **Order** and **Max videos per tab**.
4. Click **Start**. The videos appear in the **Channel videos** view within seconds.
5. Download them as JSON, CSV or Excel, or connect an integration.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `channels` | list of text | — (required) | Channels, one per line (up to 1,000): `@handle`, channel link, `/channel/UC…`, `/c/…`, `/user/…` or a `UC…` id. A link to one tab (`…/shorts`, `…/videos`, `…/streams`, `…/live`) reads that tab only. The same channel twice is read once. |
| `tabs` | list | `["videos"]` | Tabs to read: `videos`, `shorts`, `streams` (Live). |
| `sortBy` | `latest`, `popular`, `oldest` | `latest` | YouTube's sort buttons on the tab. |
| `maxResultsPerTab` | number | 50 | Videos to take from each tab of each channel, 1 to 10,000. |
| `maxConcurrency` | number | 5 | Channel tabs read at the same time, 1 to 10. |

Example:

```json
{
  "channels": ["@GoogleDevelopers", "https://www.youtube.com/@mkbhd"],
  "tabs": ["videos", "shorts"],
  "sortBy": "popular",
  "maxResultsPerTab": 100
}
```

### Output

One item per video, in the order of the tab:

```json
{
  "status": "ok",
  "note": null,
  "channel": "@GoogleDevelopers",
  "tab": "videos",
  "position": 1,
  "videoId": "i3X7Fv0Z3Uc",
  "url": "https://www.youtube.com/watch?v=i3X7Fv0Z3Uc",
  "title": "Turning raw hardware sensor data into music with Gemini",
  "type": "video",
  "viewCount": 9700,
  "viewCountText": "9.7K views",
  "publishedTimeText": "21 hours ago",
  "durationText": "1:27",
  "durationSeconds": 87,
  "thumbnailUrl": "https://i.ytimg.com/vi/i3X7Fv0Z3Uc/hq720.jpg?…",
  "channelName": "Google for Developers",
  "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
  "channelHandle": "@GoogleDevelopers",
  "channelUrl": "https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw",
  "channelIsVerified": true,
  "channelSubscriberCount": 2680000,
  "channelSubscriberCountText": "2.68M subscribers",
  "channelVideoCountText": "6.1K videos",
  "scrapedAt": "2026-10-16T18:00:00.000Z"
}
```

| Field | Meaning |
|---|---|
| `status` | `ok` (charged). Free, one item per channel tab: `no-videos` (the channel has no such tab, or nothing public in it), `not-found`, `invalid-url`, `failed`, `skipped-cost-limit`. |
| `note` | Why an item has no video; `null` when `status` is `ok`. |
| `channel`, `tab`, `position` | The channel as you gave it, the tab (`videos`, `shorts`, `streams`) and the rank of the video in it. |
| `videoId`, `url`, `title` | The video; `url` is a `/shorts/` link for a Short. |
| `type` | `video`, `short`, `stream` (past live stream), `live` (streaming now) or `upcoming`. |
| `viewCount`, `viewCountText` | Views, **rounded as YouTube shows them on channel pages** (9.7K → 9700), and as written. |
| `publishedTimeText` | Upload time as shown ("21 hours ago"); `null` for Shorts. |
| `durationText`, `durationSeconds` | Length; `null` for Shorts and live streams in progress. |
| `thumbnailUrl` | Largest thumbnail. |
| `channelName`, `channelId`, `channelHandle`, `channelUrl`, `channelIsVerified` | The channel; `channelIsVerified` is YouTube's check-mark badge. |
| `channelSubscriberCount`, `channelSubscriberCountText` | Subscribers, rounded as YouTube shows them, and as written. |
| `channelVideoCountText` | Number of videos as shown on the channel ("6.1K videos"). |
| `scrapedAt` | When the item was produced (UTC). |

The run summary (counts, errors, duration) is in the key-value store under `OUTPUT`.

### How much does it cost to scrape YouTube channel videos?

You pay **per video delivered**:

| Apify plan | Price per video | Per 1,000 videos |
|---|---|---|
| Free | $0.0007 | $0.70 |
| Starter (Bronze) | $0.0005 | $0.50 |
| Scale (Silver) | $0.00045 | $0.45 |
| Business (Gold) and above | $0.0004 | $0.40 |

Plus Apify's start fee of $0.00005 per run. **Free**: channels not found, missing or empty tabs, links that are not channels, failures, and tabs cut by your cost limit. The $5 monthly credit of Apify's Free plan covers about **7,000 videos** a month. Set **Maximum cost per run** in the run options to cap a run: the Actor stops before going over it and never delivers more than it charged.

### Is it free to try?

Yes. Apify's Free plan gives $5 of credit every month, with no card needed.

### Use it from code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("datafabrik/youtube-channel-videos").call(run_input={
    "channels": ["@mkbhd"],
    "tabs": ["videos", "shorts"],
    "maxResultsPerTab": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["status"] == "ok":
        print(item["tab"], item["title"], item["viewCount"])
```

JavaScript (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('datafabrik/youtube-channel-videos').call({ channels: ['@GoogleDevelopers'], sortBy: 'popular' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => `${i.position}. ${i.title}`));
```

### Limits

- **Views and subscribers are rounded** as YouTube shows them on channel pages ("9.7K"). Upload times are relative ("3 months ago"); YouTube gives no exact date on channel pages. For exact details and the full transcript, pass the `url`s to our [YouTube Transcript Scraper](https://apify.com/datafabrik/youtube-transcripts).
- YouTube shows **Shorts with their title and views only**: no upload time nor duration. Some channels hide their view counts: `viewCount` is then `null`.
- `popular` and `oldest` use YouTube's sort buttons. On the rare tab that has several pages but no sort button, these orders give a free `failed` item instead of a wrong order.
- Playlists, posts, members-only videos and the channel's About page are not included.
- Channels are read as a visitor who is not logged in, from the United States.

### FAQ

#### Is it legal to scrape YouTube channels?

The Actor reads public channel pages that YouTube shows to any visitor, without login. It does not collect personal data such as emails. You are responsible for how you use the data, in line with YouTube's terms; check with a lawyer for commercial reuse.

#### How do I get only the new videos of a channel every day?

Schedule a run every day with `sortBy` `latest` and a small `maxResultsPerTab` (10), then keep the `videoId`s you have not seen yet.

#### Why did a channel come back with `no-videos`?

The channel has no tab of that kind (many channels have no Shorts or Live tab), or nothing public in it. The `note` says which. It is not charged.

#### Do I need a YouTube API key or an account?

No, and there is no daily quota. The Actor uses the same public endpoints as YouTube's website.

#### Can you add a feature or build a custom scraper?

Yes: open an issue on the **Issues** tab, we answer within a day.

# Actor input Schema

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

YouTube channels, one per line (up to 1,000): @handle, https://www.youtube.com/@handle, /channel/UC…, /c/name, /user/name, or a UC… id. A link to one tab (…/videos, …/shorts, …/streams or …/live) reads that tab only.

## `tabs` (type: `array`):

Which tabs of each channel to read: Videos, Shorts, Live (past and current live streams). Each tab gives its own list.

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

YouTube's own sort buttons on the channel tab: latest, popular or oldest.

## `maxResultsPerTab` (type: `integer`):

How many videos to take from each tab of each channel (1 to 10,000).

## `maxConcurrency` (type: `integer`):

How many channel tabs are read at the same time (1 to 10). The default suits most runs.

## Actor input object example

```json
{
  "channels": [
    "@GoogleDevelopers"
  ],
  "tabs": [
    "videos"
  ],
  "sortBy": "latest",
  "maxResultsPerTab": 50,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

No description

## `summary` (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": [
        "@GoogleDevelopers"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datafabrik/youtube-channel-videos").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": ["@GoogleDevelopers"] }

# Run the Actor and wait for it to finish
run = client.actor("datafabrik/youtube-channel-videos").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": [
    "@GoogleDevelopers"
  ]
}' |
apify call datafabrik/youtube-channel-videos --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datafabrik/youtube-channel-videos"
        }
    }
}
```

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/M0pBYl6MoDNV8l3a2/builds/bUqhLsp9W6THbisA1/openapi.json
