# YouTube Channel Videos Scraper — Videos, Shorts & Live (`quarry/youtube-channel-videos-scraper`) Actor

List a channel's full catalogue with views, duration and upload age. Videos, Shorts and past live streams. No API key, no quota.

- **URL**: https://apify.com/quarry/youtube-channel-videos-scraper.md
- **Developed by:** [Quarry](https://apify.com/quarry) (community)
- **Categories:** Social media, Videos, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 video listeds

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/platform/actors/running/actors-in-store#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 — the whole catalogue, fast

List every video on a channel with views, duration, upload age and thumbnails. Videos, Shorts and past live streams. No API key and no quota — the official YouTube Data API gives you 10,000 units a day and a channel listing burns through it fast.

### Sample output

```json
{
  "videoId": "lVylRtlPOIE",
  "url": "https://www.youtube.com/watch?v=lVylRtlPOIE",
  "title": "I Granted 100 Kids Their Biggest Wish!",
  "channel": "MrBeast",
  "channelSubscriberCountText": "511M subscribers",
  "tab": "videos",
  "viewCount": 39000000,
  "viewCountText": "39M views",
  "publishedText": "8 days ago",
  "publishedApproxDate": "2026-07-25T00:00:00.000Z",
  "durationSeconds": 875,
  "durationText": "14:35",
  "thumbnailUrl": "https://i.ytimg.com/vi/lVylRtlPOIE/hqdefault.jpg",
  "isShort": false
}
```

### Why this one

- **All three tabs.** Videos, Shorts and Live in one run. Shorts use a completely different internal format and most listers silently return nothing for them.
- **Fast.** 90 videos in about one second. 678 videos across 3 channels and 2 tabs in a few seconds.
- **Filter before you pay.** `minViews`, `keywords` and `publishedWithinDays` are applied before rows are billed.
- **It reports drift.** If YouTube changes its payload shape, you get a `drift` status rather than a silently empty dataset.
- **A handle that does not exist comes back as `not_found`.** Resolution asks YouTube to resolve the vanity URL rather than taking the top search hit, so a typo'd handle never quietly returns some other channel's catalogue as a billable result.

### Input

| Field | What it does |
|---|---|
| `channels` | **Required.** Handles, URLs or `UC…` ids. |
| `tabs` | `videos`, `shorts`, `live`. Default `["videos"]`. |
| `maxVideosPerChannel` | Cap per channel per tab. Default 200. |
| `minViews` / `keywords` | Filter before billing. |
| `publishedWithinDays` | Recent uploads only. |

```json
{ "channels": ["@MrBeast", "@veritasium"], "tabs": ["videos", "shorts"], "maxVideosPerChannel": 120 }
```

### Honest limits

- **Upload dates are approximate.** Channel listings only expose relative ages ("8 days ago"), so `publishedApproxDate` is derived from that. An exact timestamp would cost one extra request per video. The field name says what it is.
- **Shorts carry no upload date or duration** on the listing tile — YouTube doesn't put them there. `publishedText` and `durationSeconds` are `null` for Shorts rather than guessed.
- **Shorts view counts are rounded** by YouTube itself ("15 million views"), so they are less precise than long-form counts.

### Status values

Every channel × tab resolves to one of: `ok`, `not_found` (no channel owns that handle), `empty` (the tab has nothing, or filters kept nothing), `transport` (network), or `drift` (YouTube changed the payload shape).

A run that lists nothing writes a single summary row instead of an empty dataset, so your schedule can tell "checked and quiet" apart from "broken":

```json
{ "type": "no_changes", "listingsAttempted": 1, "videosFound": 5, "videosFiltered": 5, "notFound": 0, "checkedAt": "2026-08-05T12:07:00.335Z" }
```

Video rows never carry a `type` field, so filtering the summary out downstream is one comparison. The summary row is never billed.

### Pairs with

Our transcript and comments scrapers — feed this actor's `videoId` output straight into either for full-catalogue analysis.

### Pricing

Pay per video listed. Filtered-out videos and failed channel lookups cost nothing.

# Actor input Schema

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

Handles (@mkbhd), channel URLs, or UC… ids.

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

Which tabs to list.

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

How far back to page per channel, newest first. Bounds cost on large channels.

## `minViews` (type: `integer`):

Drop videos below this view count. Useful for filtering a back catalogue down to what performed. 0 = keep everything.

## `keywords` (type: `array`):

Keep only videos whose title contains any of these terms. Leave empty for all videos.

## `publishedWithinDays` (type: `integer`):

Approximate — YouTube only exposes relative ages on listings. Videos with no date are kept.

## `maxItems` (type: `integer`):

Hard ceiling on billable videos for the whole run. 0 = no limit.

## `concurrency` (type: `integer`):

How many channels to fetch in parallel. Raise for speed, lower if YouTube throttles you.

## Actor input object example

```json
{
  "channels": [
    "https://www.youtube.com/@MrBeast"
  ],
  "tabs": [
    "videos"
  ],
  "maxVideosPerChannel": 200,
  "minViews": 0,
  "publishedWithinDays": 0,
  "maxItems": 0,
  "concurrency": 3
}
```

# 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": [
        "https://www.youtube.com/@MrBeast"
    ]
};

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

# Run the Actor and wait for it to finish
run = client.actor("quarry/youtube-channel-videos-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "https://www.youtube.com/@MrBeast"
  ]
}' |
apify call quarry/youtube-channel-videos-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=quarry/youtube-channel-videos-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/fotxoL9Lu4phxthqr/builds/SOgfKU8UVLMS2pDqe/openapi.json
