# YouTube Channel Scraper: Every Video & Short (`luzivanlt/youtube-channel-videos-scraper`) Actor

Every upload of a YouTube channel, newest first: videos, Shorts and live streams in one list. $0.50 per 1,000 videos. Each typed, with the channel's subscribers and links.

- **URL**: https://apify.com/luzivanlt/youtube-channel-videos-scraper.md
- **Developed by:** [Luzi](https://apify.com/luzivanlt) (community)
- **Categories:** Social media, Videos, Marketing
- **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.
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

## YouTube Channel Scraper: Every Video & Short

Get every upload of a YouTube channel, newest first: regular videos, Shorts
and live streams in one list, each marked with its type. Every row also
carries the channel's subscribers, total views, country, joined date and
links, so one file holds the videos and who made them. No YouTube account,
login or cookies needed.

Tested daily. Latest checks: four whole channels read back to their first
upload, 3,003 videos in 3 minutes; three matched YouTube's own count exactly
and one came within a video (495 of 496).

### What does this Actor do?

You give it links to YouTube channels (or just their @handles). For each
channel it reads the channel's uploads list from the newest upload back, and
saves one row per video until it reaches your limit or the channel's first
upload.

Each row comes with:

- the video's id, link, embed link, title and thumbnail, with every size of
  the thumbnail YouTube offers
- its type: `video`, `short` or `live`
- its duration, views and when it was posted (as YouTube shows it, such as
  "3 days ago")
- for a live stream: whether it is live now, upcoming (with its scheduled
  time) or over, and how many people are watching or waiting
- its place in the channel's uploads (1 = the newest)
- whether it is a collaboration with another channel (and, when it is, the
  other channels' names, handles, links and subscribers), and any badge on its
  thumbnail (such as "LIVE" or "Upcoming")
- the channel's id, name, handle, picture, verified or official-artist mark,
  description, country (with its two-letter code), subscribers, total views,
  joined date, video count, links and RSS feed

### Why use it?

- **The whole channel, not just the Videos tab.** Videos, Shorts and live
  streams come in one list, newest first, so nothing is split over three runs.
- **Each upload typed.** Every row says whether it is a video, a Short or a
  live stream, and you can leave any type out.
- **Complete, and it tells you so.** When every type is included, the run's
  status compares what it read with the count YouTube shows for the channel's
  uploads.
- **Channel facts on every row.** Subscribers, total views, country, joined
  date and the channel's own links, ready to compare channels in one sheet.
- **Use the data anywhere.** Download as JSON, CSV or Excel, or send it to
  your own tools through Apify's API and integrations.

### How to use it

1. Paste one or more channel links into **Channel links**.
2. Optionally, set **Max videos per channel** (leave it empty for the whole
   channel), and turn off the types you do not want.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   videos or download them.

#### Links that work

A channel link as in your browser's address bar
(`https://www.youtube.com/@veritasium`, `https://www.youtube.com/channel/UCHnyfMqiRRG1u-2MsSQLbXA`,
`/c/…` or `/user/…`), any tab of it (`…/@veritasium/videos`), or the handle
(`@veritasium`) or channel id (`UCHnyfMqiRRG1u-2MsSQLbXA`) on its own. Video,
playlist and search links are not supported: this Actor reads the uploads of
the channels you name.

### Input

| Field                                              | What it does                                          | Default        |
| -------------------------------------------------- | ----------------------------------------------------- | -------------- |
| **Channel links** (`startUrls`)                    | The channels to read. Required.                       | —              |
| **Max videos per channel** (`maxVideosPerChannel`) | Stop after this many videos per channel, newest first | the whole list |
| **Include videos** (`includeVideos`)               | Save regular (long) videos                            | `true`         |
| **Include Shorts** (`includeShorts`)               | Save Shorts                                           | `true`         |
| **Include live streams** (`includeLiveStreams`)    | Save live streams: past, live now and upcoming        | `true`         |

Example input:

```json
{
  "startUrls": ["https://www.youtube.com/@veritasium"],
  "maxVideosPerChannel": 500,
  "includeShorts": false
}
```

### Output

One row per video. An example, with made-up values:

```json
{
  "video_id": "AbCdEfGhIjK",
  "url": "https://www.youtube.com/watch?v=AbCdEfGhIjK",
  "embed_url": "https://www.youtube.com/embed/AbCdEfGhIjK",
  "title": "A video title",
  "video_type": "video",
  "position": 1,
  "duration_text": "34:32",
  "duration_seconds": 2072,
  "view_count": 7100000,
  "view_count_text": "7.1M views",
  "published_time_text": "3 days ago",
  "live_status": null,
  "scheduled_start_text": null,
  "concurrent_viewers": null,
  "badges": [],
  "thumbnail_url": "https://i.ytimg.com/vi/AbCdEfGhIjK/hqdefault.jpg?…",
  "thumbnails": [
    { "url": "https://i.ytimg.com/vi/AbCdEfGhIjK/hqdefault.jpg?…", "width": 168, "height": 94 },
    { "url": "https://i.ytimg.com/vi/AbCdEfGhIjK/hqdefault.jpg?…", "width": 336, "height": 188 }
  ],
  "byline_text": "A Channel and Another Channel",
  "is_collaboration": true,
  "collaborators": [
    {
      "name": "Another Channel",
      "handle": "@anotherchannel",
      "channel_id": "UC2222222222222222222222",
      "url": "https://www.youtube.com/channel/UC2222222222222222222222",
      "subscribers_text": "1.28M subscribers",
      "subscriber_count": 1280000,
      "verified": true,
      "is_artist": false,
      "avatar_url": "https://yt3.ggpht.com/…"
    }
  ],
  "channel_id": "UC1111111111111111111111",
  "channel_name": "A Channel",
  "channel_handle": "@achannel",
  "channel_url": "https://www.youtube.com/channel/UC1111111111111111111111",
  "channel_rss_url": "https://www.youtube.com/feeds/videos.xml?channel_id=UC1111111111111111111111",
  "channel_avatar_url": "https://yt3.ggpht.com/…",
  "channel_verified": true,
  "channel_is_artist": false,
  "channel_description": "Videos about things.",
  "channel_country": "United States",
  "channel_country_code": "US",
  "channel_subscribers_text": "21.4M subscribers",
  "channel_subscriber_count": 21400000,
  "channel_view_count": 4666228082,
  "channel_joined_date": "2010-07-21",
  "channel_video_count": 541,
  "channel_upload_count": 541,
  "channel_links": [{ "title": "Shop", "url": "https://shop.example.com/" }],
  "source_url": "https://www.youtube.com/@achannel"
}
```

| Field                      | What it holds                                                                           |
| -------------------------- | --------------------------------------------------------------------------------------- |
| `video_id`                 | The video's id                                                                          |
| `url`                      | A link to the video (a `/shorts/` link for a Short)                                     |
| `embed_url`                | A link to embed the video in a web page                                                 |
| `title`                    | The title                                                                               |
| `video_type`               | `video`, `short` or `live`                                                              |
| `position`                 | Its place in the channel's uploads, 1 = the newest                                      |
| `duration_text`            | The duration as shown ("34:32"; empty while live or upcoming)                           |
| `duration_seconds`         | The same in seconds                                                                     |
| `view_count`               | Views (YouTube rounds counts above 1,000, such as 7.1M → 7100000)                       |
| `view_count_text`          | Views as YouTube shows them                                                             |
| `published_time_text`      | When it was posted, as YouTube shows it ("3 days ago", "Streamed 2 weeks ago")          |
| `live_status`              | For a live stream: `live`, `upcoming` or `was_live`; empty otherwise                    |
| `scheduled_start_text`     | For an upcoming stream: its scheduled time, as shown                                    |
| `concurrent_viewers`       | People watching (live now) or waiting (upcoming)                                        |
| `badges`                   | Badges on the thumbnail other than the duration, such as "LIVE" or "Upcoming"           |
| `thumbnail_url`            | The largest thumbnail shown                                                             |
| `thumbnails`               | Every size of the thumbnail shown, each with `url`, `width` and `height`                |
| `byline_text`              | The channel line under the title ("A Channel and Another Channel")                      |
| `is_collaboration`         | Whether the video is shared with another channel                                        |
| `collaborators`            | A collaboration's other channels (name, handle, id, link, subscribers); empty otherwise |
| `channel_id`               | The channel's id                                                                        |
| `channel_name`             | The channel's name                                                                      |
| `channel_handle`           | The channel's `@` handle                                                                |
| `channel_url`              | A link to the channel                                                                   |
| `channel_rss_url`          | The channel's RSS feed of new uploads                                                   |
| `channel_avatar_url`       | The channel's picture                                                                   |
| `channel_verified`         | Whether the channel has the verified mark                                               |
| `channel_is_artist`        | Whether the channel is an official artist channel                                       |
| `channel_description`      | The channel's description                                                               |
| `channel_country`          | The channel's country, when it shows one                                                |
| `channel_country_code`     | The same as a two-letter ISO code ("US"); empty for a name it does not know             |
| `channel_subscribers_text` | Subscribers as YouTube shows them ("21.4M subscribers")                                 |
| `channel_subscriber_count` | The same as a number (rounded as YouTube rounds it)                                     |
| `channel_view_count`       | The channel's total views, exact                                                        |
| `channel_joined_date`      | When the channel joined YouTube, as `YYYY-MM-DD`                                        |
| `channel_video_count`      | The video count on the channel's About panel                                            |
| `channel_upload_count`     | The count YouTube shows on the channel's uploads list                                   |
| `channel_links`            | The links on the channel's About panel, with YouTube's redirect removed                 |
| `source_url`               | The channel link or handle you gave                                                     |

Not included: an exact upload date (YouTube's lists show only "3 days ago"),
exact view counts, likes, comment counts, descriptions and tags of each video,
playlists, and posts.

### How much does it cost?

You pay for what you get:

- **$0.50 per 1,000 videos** ($0.0005 a video). Videos, Shorts and live streams cost the same. Each is charged once per run.
- No start fee, and nothing per channel.

So a channel with 1,000 uploads costs $0.50. If you set a maximum cost for a run, the Actor stops when it reaches it and keeps every video saved so far.

### How long does a run take?

About 15 seconds for the newest 50 videos of two channels, and about 3
minutes for four whole channels (3,003 videos).

### Good to know

- **You may get a few videos fewer than the channel's count.** YouTube's
  count can include uploads it does not list for visitors. The two counts on
  a row (`channel_video_count` and `channel_upload_count`) can differ too.
- **Dates are relative.** YouTube's lists show when a video was posted only
  as "3 days ago" or "2 years ago"; the row keeps it as shown.
- **Give each channel once.** The same channel given as a handle and as its
  channel id is read twice, and each copy may show part of the list.
- **Check your links first.** A link that is not a YouTube channel stops the
  run before anything is read, and the message names it.
- **One channel that cannot be read does not stop the run.** The other
  channels carry on, and the run's status lists the channels that could not
  be read. The run fails only when no channel could be read.
- **A channel with no uploads is not an error.** It saves nothing.

### FAQ

**Do I need a YouTube account or cookies?**
No. The Actor reads what anyone can see on the channel's pages.

**Can I get only the newest videos?**
Yes. Set **Max videos per channel**: the list is read newest first, so a
limit of 20 gives the 20 newest uploads.

**Can I run it from my own code, on a schedule, or with other apps?**
Yes. Like any Apify Actor, you can start it through the Apify API, run it on a
schedule, and connect it to other apps with Apify's integrations and webhooks.

### Is it legal to scrape YouTube?

This Actor reads only what anyone can see on a channel's pages without logging
in. Check YouTube's terms and the laws that apply to you before you use the
data, and only collect personal data when you have a legitimate reason to. If
you are unsure, ask a lawyer.

### Support

Found a problem or missing a feature? Open an issue on the **Issues** tab and
include the run's link.

***

This Actor is not affiliated with, endorsed by or sponsored by YouTube or
Google.

# Actor input Schema

## `startUrls` (type: `array`):

Links to YouTube channels (https://www.youtube.com/@name, /channel/UC…, /c/name or /user/name, any of their tabs), or a bare @handle or UC… channel id.

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

Stop reading a channel after this many videos, newest first. Leave empty to read its whole uploads list.

## `includeVideos` (type: `boolean`):

Save the channel's regular (long) videos.

## `includeShorts` (type: `boolean`):

Save the channel's Shorts.

## `includeLiveStreams` (type: `boolean`):

Save the channel's live streams: past, live now and upcoming.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.youtube.com/@veritasium",
    "https://www.youtube.com/channel/UC_wb9FQkewAlh7i2bCB5FtQ"
  ],
  "maxVideosPerChannel": 50,
  "includeVideos": true,
  "includeShorts": true,
  "includeLiveStreams": true
}
```

# Actor output Schema

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

Every video the run saved, one row each.

# 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 = {
    "startUrls": [
        "https://www.youtube.com/@veritasium",
        "https://www.youtube.com/channel/UC_wb9FQkewAlh7i2bCB5FtQ"
    ],
    "maxVideosPerChannel": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/youtube-channel-videos-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 = {
    "startUrls": [
        "https://www.youtube.com/@veritasium",
        "https://www.youtube.com/channel/UC_wb9FQkewAlh7i2bCB5FtQ",
    ],
    "maxVideosPerChannel": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("luzivanlt/youtube-channel-videos-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 '{
  "startUrls": [
    "https://www.youtube.com/@veritasium",
    "https://www.youtube.com/channel/UC_wb9FQkewAlh7i2bCB5FtQ"
  ],
  "maxVideosPerChannel": 50
}' |
apify call luzivanlt/youtube-channel-videos-scraper --silent --output-dataset

```

## MCP server setup

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