# YouTube Channel Videos Scraper — Metadata & Metrics (`khadinakbar/youtube-channel-videos-scraper`) Actor

Scrape public YouTube channel videos and Shorts with titles, descriptions, dates, views, likes, comments, duration, thumbnails, and channel metadata. No cookies required.

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

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

Turn known YouTube channels into a clean, analysis-ready inventory of public videos and Shorts. Give the Actor channel URLs, `@handles`, or channel IDs; it returns one validated dataset row per video with its URL, title, description, publish time, duration, thumbnail, public engagement metrics, channel identity, and collection provenance.

This YouTube channel video scraper is for a precise job: **you already know which channels matter and need their recent or popular public content as structured data**. It does not require your YouTube cookies, Google login, browser session, or personal YouTube API key.

Use [the prefilled Actor input page](https://apify.com/khadinakbar/youtube-channel-videos-scraper/input) when you want to verify one channel with a bounded 10-video run.

### Decide in 30 seconds

| Your job | Use this Actor? | Recommended route |
| --- | --- | --- |
| Export videos or Shorts from known channels | Yes | Add channel URLs or handles to `channelUrls`. |
| Monitor new uploads from a fixed creator or competitor list | Yes | Use `sortBy: "latest"` and a bounded date window. |
| Compare public views, likes, comments, duration, and posting patterns | Yes | Keep `maxTotalVideos` small first, then export the dataset. |
| Discover channels from a topic or keyword | Not first | Start with [YouTube Search Scraper](https://apify.com/khadinakbar/youtube-search-scraper), then pass its `channelUrl` or `channelId` values here. |
| Collect comments after selecting videos | Not directly | Send this Actor's `videoUrl` or `videoId` values to [YouTube Comments Scraper](https://apify.com/khadinakbar/youtube-comments-scraper). |
| Download media, audio, captions, or transcripts | No | Use a purpose-built downloader or transcript Actor. |
| Access private, deleted, age-gated, or login-only content | No | Those surfaces are outside this Actor's public-data scope. |

### A real workflow: from channel list to editorial decision

Imagine a content strategist starts Monday with 12 competitor channels and one question: “What did they publish in the last 30 days, and which formats earned visible engagement?” Search results are the wrong source because ranking changes by query, location, and personalization. The strategist already has the channel list.

They run this Actor with `contentType: "all"`, a start date, `maxVideosPerChannel: 25`, and a whole-run cap. The dataset becomes the evidence table: titles show recurring themes, `durationSeconds` separates short and long formats, `publishedAt` reveals cadence, and the public metric fields support a current-snapshot comparison. When a high-interest video needs audience analysis, its `videoUrl` flows directly into the comments Actor. The decision is no longer based on opening 12 channel tabs by hand.

That workflow is intentionally bounded. It does not pretend a public metric snapshot is historical performance data, and it does not interpret a missing like count as zero.

### What one dataset row contains

Each row represents one public long-form video or YouTube Short. The flat record works in CSV, JSON, spreadsheets, BI tools, databases, Make, n8n, and AI-agent pipelines.

| Field group | Fields | What it answers |
| --- | --- | --- |
| Video identity | `videoId`, `videoUrl`, `title`, `description` | What is the item and where is its public page? |
| Channel identity | `channelId`, `channelHandle`, `channelName`, `channelUrl`, `channelSubscriberCount` | Which channel published it? |
| Time and format | `publishedAt`, `durationSeconds`, `durationText`, `contentType`, `isShort`, `isLive`, `isUpcoming` | When and in what format was it published? |
| Public metrics | `viewCount`, `likeCount`, `commentCount`, `engagementRate` | What visible engagement snapshot did the provider return? |
| Media and labels | `thumbnailUrl`, `badges`, `genre` | What display and classification metadata is available? |
| Provenance | `provider`, `input`, `sortBy`, `resultPosition`, `page`, `scrapedAt` | How, where, and when was the row collected? |

`engagementRate` is calculated as `(likeCount + commentCount) / viewCount` only when all three usable public counts exist and views are greater than zero. If YouTube or the provider omits a count, the Actor omits the rate instead of understating it.

Optional fields vary by video, channel, region, and provider response. Missing data stays missing; the Actor does not invent placeholder values or write error rows into the dataset.

### Quick start recipes

#### Recipe 1: ten recent long-form videos

Use this first to verify the channel and inspect the output shape at a bounded cost.

```json
{
  "channelUrls": ["https://www.youtube.com/@MrBeast"],
  "contentType": "videos",
  "maxVideosPerChannel": 10,
  "maxPagesPerContentType": 1,
  "maxTotalVideos": 10,
  "sortBy": "latest"
}
````

#### Recipe 2: recent uploads across a reporting window

`publishedAfter` is inclusive; `publishedBefore` is exclusive. Both accept real UTC calendar dates in `YYYY-MM-DD` form.

```json
{
  "channelUrls": [
    "https://www.youtube.com/@TED",
    "https://www.youtube.com/@NASA"
  ],
  "contentType": "all",
  "maxVideosPerChannel": 25,
  "maxPagesPerContentType": 2,
  "maxTotalVideos": 50,
  "sortBy": "latest",
  "publishedAfter": "2026-06-01",
  "publishedBefore": "2026-07-01"
}
```

When `contentType` is `all`, the long-form feed is processed before the Shorts feed and both share the per-channel cap. Raise `maxVideosPerChannel` if you need room for both formats.

#### Recipe 3: popular Shorts from a channel ID

```json
{
  "channelUrls": ["UCX6OQ3DkcsbYNE6H8uQQuVA"],
  "contentType": "shorts",
  "maxVideosPerChannel": 20,
  "maxPagesPerContentType": 2,
  "maxTotalVideos": 20,
  "sortBy": "popular"
}
```

Provider rankings can differ slightly. Treat `popular` as the selected provider's current feed order, not as an immutable YouTube-wide ranking.

### Input reference and cost controls

| Input | Type and default | Use it for | Important boundary |
| --- | --- | --- | --- |
| `channelUrls` | array, required | Channel URLs, `@handles`, or IDs beginning `UC` | 1–100 entries; video and playlist URLs are rejected. |
| `contentType` | `videos` | `videos`, `shorts`, or `all` | `all` shares one per-channel result cap. |
| `maxVideosPerChannel` | integer, `50` | Cap saved rows for each channel | 1–500. |
| `maxPagesPerContentType` | integer, `10` | Bound provider pagination per selected feed | 1–50; this is not a row count. |
| `maxTotalVideos` | integer, `500` | Cap all saved and billable rows in the run | 1–5,000; strongest whole-run event-cost control. |
| `sortBy` | `latest` | Request recent-first or popularity-oriented ordering | `latest` or `popular`. |
| `publishedAfter` | omitted | Keep records on or after a UTC date | Real `YYYY-MM-DD` date; rows without a machine-readable date are excluded. |
| `publishedBefore` | omitted | Keep records before a UTC date | Exclusive upper bound; must be later than `publishedAfter`. |
| `providerOrder` | `scrapecreators-first` | Select fallback order or isolate a provider for diagnosis | Single-provider modes remove fallback resilience. |
| `includeRawData` | `false` | Diagnose provider field drift | Adds a capped raw object and makes rows less convenient for agents and sheets. |

API inputs are validated without coercion. For example, `"10"` is not accepted where the schema declares the integer `10`, `"true"` is not accepted as a boolean, and a rollover date such as `2025-02-30` is rejected. This keeps UI, API, and agent behavior consistent.

### Output example

```json
{
  "recordType": "video",
  "contentType": "videos",
  "provider": "scrapecreators",
  "input": "https://www.youtube.com/@MrBeast",
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "channelHandle": "MrBeast",
  "channelName": "MrBeast",
  "channelUrl": "https://www.youtube.com/@MrBeast",
  "videoId": "xvFZjo5PgG0",
  "videoUrl": "https://www.youtube.com/watch?v=xvFZjo5PgG0",
  "title": "A public video title",
  "description": "A public video description returned by the provider.",
  "publishedAt": "2026-07-01T00:00:00.000Z",
  "durationSeconds": 823,
  "durationText": "13:43",
  "thumbnailUrl": "https://i.ytimg.com/vi/xvFZjo5PgG0/maxresdefault.jpg",
  "viewCount": 23456789,
  "likeCount": 1200000,
  "commentCount": 18342,
  "engagementRate": 0.0519,
  "isShort": false,
  "sortBy": "latest",
  "resultPosition": 1,
  "page": 1,
  "scrapedAt": "2026-07-18T12:00:00.000Z"
}
```

The default key-value store also contains:

- `OUTPUT`: compact terminal outcome, row and charge counts, cost figures, memory allocation, and warnings.
- `RUN_SUMMARY`: detailed input, providers, attempts, status codes, pagination, filters, validation, billing, and stop reason.

Use the dataset for records and `OUTPUT` for orchestration. Do not infer success from an HTTP or Actor run status alone.

### Run outcomes for automations and AI agents

| Outcome | Transport state | Meaning | Recommended agent action |
| --- | --- | --- | --- |
| `COMPLETE` | succeeded | Requested bounded work completed without recorded data-quality warnings | Consume rows. |
| `PARTIAL` | succeeded | Usable rows exist, but a route, validation, write, or event-cap warning occurred | Consume with warnings; decide whether to retry the missing scope. |
| `VALID_EMPTY` | succeeded | The request was valid but no matching public rows were available, or the event cap prevented provider work | Check dates, channel availability, and `stopReason`; do not invent rows. |
| `INVALID_INPUT` | succeeded | Input type, value, date, or channel reference was invalid | Correct the named field; do not retry unchanged. |
| `CONFIG_ERROR` | failed | Owner-managed provider credentials or internal configuration prevented work | Escalate; changing channel input will not fix it. |
| `UPSTREAM_FAILED` | failed | Every configured provider route failed before a usable row was saved | Retry with backoff or use a diagnostic provider mode. |

Continuation tokens are provider-specific and remain internal. There is no public resume-token input. To bound or deepen a run, change `maxPagesPerContentType`, `maxVideosPerChannel`, and `maxTotalVideos`; never copy a continuation token between providers.

### Pricing with worked examples

This Actor uses **Pay per event + Apify platform usage**.

| Event | Price | When it is charged |
| --- | ---: | --- |
| `apify-actor-start` | `$0.00005` | One event per allocated GB or part thereof, with a one-event minimum. |
| `video-scraped` | `$0.005` | Once for each validated video or Short successfully persisted to the dataset. |

At the default 512 MB allocation, the start event count is one:

A bounded run of 10 records costs `$0.05005` in named event charges at that memory allocation.

- 1 saved video: `1 × $0.00005 + 1 × $0.005 = $0.00505`
- 10 saved records: `1 × $0.00005 + 10 × $0.005 = $0.05005`
- 50 saved videos: `1 × $0.00005 + 50 × $0.005 = $0.25005`

At 4 GB, 10 saved videos cost `4 × $0.00005 + 10 × $0.005 = $0.05020` in event charges. Apify compute, storage, network, and any proxy usage are additional. The Actor reports both the maximum bounded event estimate before provider work and actual named-event counts afterward.

Set `maxTotalVideos` before increasing page depth. A date filter can reduce saved rows and event charges, but provider pages still use compute and provider capacity while the Actor looks for matching dates.

### Use through the API

#### cURL

Keep the token in an environment variable and send it in the authorization header, not in a URL.

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/khadinakbar~youtube-channel-videos-scraper/runs?waitForFinish=60' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "channelUrls": ["https://www.youtube.com/@TED"],
    "contentType": "videos",
    "maxVideosPerChannel": 10,
    "maxPagesPerContentType": 1,
    "maxTotalVideos": 10,
    "sortBy": "latest"
  }'
```

Read `data.defaultDatasetId` for rows and `data.defaultKeyValueStoreId` for `OUTPUT` and `RUN_SUMMARY`. If the run is still active after the wait window, poll the run endpoint before reading evidence.

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/youtube-channel-videos-scraper').call({
  channelUrls: ['https://www.youtube.com/@TED'],
  contentType: 'all',
  maxVideosPerChannel: 20,
  maxPagesPerContentType: 2,
  maxTotalVideos: 20,
  sortBy: 'latest'
});

const [{ items }, output] = await Promise.all([
  client.dataset(run.defaultDatasetId).listItems(),
  client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT')
]);

console.log(output?.value?.outcome, items.length);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("khadinakbar/youtube-channel-videos-scraper").call(run_input={
    "channelUrls": ["https://www.youtube.com/@TED"],
    "contentType": "videos",
    "maxVideosPerChannel": 10,
    "maxPagesPerContentType": 1,
    "maxTotalVideos": 10,
    "sortBy": "latest",
})

rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
output = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")
print(output["value"]["outcome"], len(rows))
```

### Agent and MCP prompt card

When this Actor is exposed through Apify's Actors MCP server, route a request here only if the user provides known channels or channel identifiers.

> **Agent prompt:** Collect 10 recent videos from the supplied channel, inspect `OUTPUT`, return warnings for `PARTIAL`, and report `VALID_EMPTY` without inventing data.

```text
Use khadinakbar--youtube-channel-videos-scraper to collect up to 10 recent
long-form videos from https://www.youtube.com/@TED. Set one provider page and
a whole-run cap of 10. Return videoId, videoUrl, title, publishedAt,
durationSeconds, viewCount, likeCount, and commentCount. Then inspect OUTPUT.
If outcome is PARTIAL, explain the warnings. If VALID_EMPTY, say that no matching
public rows were returned. Never substitute made-up metrics or retry invalid input.
```

Agent routing contract:

- Required entity: at least one known public channel URL, `@handle`, or channel ID.
- Output entity: one public video or Short per dataset row.
- Freshness: `scrapedAt` is collection time; public metrics are a snapshot, not a time series.
- Side effects: starts a paid Actor run and may persist billable dataset rows.
- Cost controls: set row and page caps explicitly.
- Failure inspection: read `OUTPUT`, then `RUN_SUMMARY` when the outcome is not `COMPLETE`.
- Pagination: controlled by bounded inputs; no cross-provider continuation token is exposed.

### Limits, recovery, and honest expectations

| Symptom | Likely reason | Recovery |
| --- | --- | --- |
| Fewer rows than expected | Date filter, duplicate IDs, missing dates, public availability, or result caps | Inspect `RUN_SUMMARY`, then widen one boundary deliberately. |
| No rows with `VALID_EMPTY` | Valid channel but no matching public items, or event cap blocked work | Check `stopReason`, dates, content type, and charge cap. |
| `PARTIAL` with data | A provider route failed or a row could not be validated/persisted | Keep usable rows, inspect warnings, and retry only the missing scope. |
| Provider-specific failure | Credential rejection, throttling, timeout, or upstream shape change | Restore default fallback order; use an `*-only` mode only for diagnosis. |
| Different order between runs | Public feeds and provider ordering changed | Treat `resultPosition` as run-scoped, not permanent rank. |
| Missing public counts | YouTube/provider did not expose them for that item | Preserve nullability; do not convert missing values to zero. |

The Actor retries transient request failures and can fall back between two owner-managed public-data providers. Provider continuation tokens are opaque and are never forwarded across providers. It deduplicates video IDs across inputs and selected feed types, validates a complete record before persistence, and couples each successful dataset write to the `video-scraped` event.

No scraper can guarantee an exhaustive historical archive of YouTube. Deleted, private, restricted, unavailable, or provider-omitted videos may not appear. Public counts can change immediately after collection.

### Verification snapshot

On 2026-07-18, the Actor was fresh-pulled from live build `1.3.1` and rebuilt through v1.4. Local validation finished with 32 passing tests, 95.65% helper-module line coverage, 85.15% branch coverage, valid Apify schemas, clean syntax checks, and an npm audit with zero known vulnerabilities. The review caught and fixed cross-provider continuation-token reuse, permissive API coercion, invalid calendar-date rollover, memory-insensitive start estimates, incomplete engagement-rate semantics, ambiguous bare video IDs, an SDK charge-limit state that could disagree with the persisted dataset, and a 4 GB MCP run whose platform-expanded start count was larger than the SDK's explicit-call count.

Build `1.4.3` completed a reviewed 26/26 REST acceptance matrix with zero unexpected failures at 512 MB. A separate real Actors MCP call against build `1.4.4` at 4 GB then found a semantic reporting defect that the REST matrix could not expose: Apify correctly expanded one explicit `apify-actor-start` call to four billable start events, while the old `OUTPUT` reported one. Build `1.4.5` is the corrected release target and must independently pass the full 26-case REST matrix, a real 4 GB MCP call, the live-release verifier, and a fresh source readback before handoff. The pinned run IDs live in the release evidence rather than being hidden behind an aggregate success claim.

This is engineering evidence, not a claim that YouTube or either upstream provider will always return every field. Final cloud acceptance evidence is tied to the deployed build and its pinned run IDs rather than inferred from a `SUCCEEDED` transport status.

### Responsible use

Use this Actor for public YouTube metadata you are permitted to process. You are responsible for applicable law, YouTube terms, privacy obligations, contractual restrictions, and content rights. Do not use it to access private data, evade controls, identify sensitive individuals, or redistribute copyrighted media without permission. Apply appropriate retention, access, and deletion controls to exported datasets.

### Frequently asked questions

#### Does it download YouTube videos or audio?

No. It returns structured public metadata and metric snapshots, not media files, audio, captions, or transcripts.

#### Does it need my YouTube API key or cookies?

No. Provider credentials are managed by the Actor owner. Users provide channel references and limits, not personal YouTube credentials.

#### Can it find channels for a topic?

This Actor expects known channels. Use `youtube-search-scraper` for keyword discovery, then map its `channelUrl` or `channelId` output into `channelUrls` here.

#### How do I collect comments from the returned videos?

Pass each `videoUrl` to `startUrls`, or each `videoId` to `videoIds`, in `youtube-comments-scraper`. This is a schema-confirmed downstream handoff, not a generic cross-link.

#### Why can engagement rate be absent?

The rate requires views, likes, and comments. If any public count is unavailable, omitting the derived rate is more accurate than treating the missing count as zero.

# Actor input Schema

## `channelUrls` (type: `array`):

Use this when you want public videos from one or more known YouTube channels. Accepts channel URLs such as https://www.youtube.com/@MrBeast, a handle such as @MrBeast, or a channel ID beginning UC. The prefill is a public channel for a quick test. This is not for video URLs, playlists, keyword search, comments, or private channels.

## `contentType` (type: `string`):

Use this to choose which public channel feed to collect. Select videos for long-form videos, shorts for YouTube Shorts, or all to process both feeds. Defaults to videos for a focused and predictable run. This does not download video media or transcripts.

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

Use this to cap how many normalized rows are saved for each channel across the selected content types. Accepts whole numbers from 1 to 500 and defaults to 50; the prefill is 10. This is the main per-channel billing and volume guard. It is not a request-page limit.

## `maxPagesPerContentType` (type: `integer`):

Use this to limit provider pagination for each channel's video or Shorts feed. Accepts whole numbers from 1 to 50 and defaults to 10; the prefill is 1 for a fast check. It protects against unexpectedly deep feeds. It is not a direct row-count limit.

## `maxTotalVideos` (type: `integer`):

Use this to cap all saved video and Short rows across the entire run. Accepts whole numbers from 1 to 5000 and defaults to 500; the prefill is 10. This is the strongest whole-run cost guard. It does not set an Apify platform-usage cap.

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

Use this to request newest-first or popularity-oriented channel ordering from the provider. Accepted values are latest and popular, and the default is latest. Providers can differ slightly in their ranking and freshness. This is not a date filter.

## `publishedAfter` (type: `string`):

Use this to keep only records published on or after a UTC calendar date. Enter an ISO date such as 2025-01-01; omit it to keep every returned date. Rows with no machine-readable publish date are excluded while a date filter is active. This is not a relative date phrase such as last month.

## `publishedBefore` (type: `string`):

Use this to keep only records published before a UTC calendar date. Enter an ISO date such as 2025-12-31; omit it to keep every returned date. Rows with no machine-readable publish date are excluded while a date filter is active. This is not an inclusive end-of-day timestamp.

## `providerOrder` (type: `string`):

Use this to select the public-data provider route and fallback order. ScrapeCreators first is the default because its channel endpoint was probed with the normalized fields; SociaVault is the redundant fallback. Defaults to ScrapeCreators first. This option does not use browser automation, YouTube cookies, or a personal API key.

## `includeRawData` (type: `boolean`):

Use this only when debugging provider field drift or building a custom parser. When enabled, the original provider item is attached to each dataset row and capped to keep records bounded. Defaults to false because raw payloads are not ideal for spreadsheets or AI-agent output. This does not return private YouTube data.

## Actor input object example

```json
{
  "channelUrls": [
    "https://www.youtube.com/@MrBeast"
  ],
  "contentType": "videos",
  "maxVideosPerChannel": 10,
  "maxPagesPerContentType": 1,
  "maxTotalVideos": 10,
  "sortBy": "latest",
  "publishedAfter": "2025-01-01",
  "publishedBefore": "2025-12-31",
  "providerOrder": "scrapecreators-first",
  "includeRawData": false
}
```

# Actor output Schema

## `results` (type: `string`):

Normalized public YouTube channel video and Short metadata.

## `output` (type: `string`):

Compact terminal outcome, counts, charges, and warnings.

## `runSummary` (type: `string`):

Provider attempts, pagination, filters, costs, and terminal diagnostics.

# 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 = {
    "channelUrls": [
        "https://www.youtube.com/@MrBeast"
    ],
    "contentType": "videos",
    "maxVideosPerChannel": 10,
    "maxPagesPerContentType": 1,
    "maxTotalVideos": 10,
    "sortBy": "latest",
    "providerOrder": "scrapecreators-first",
    "includeRawData": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/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 = {
    "channelUrls": ["https://www.youtube.com/@MrBeast"],
    "contentType": "videos",
    "maxVideosPerChannel": 10,
    "maxPagesPerContentType": 1,
    "maxTotalVideos": 10,
    "sortBy": "latest",
    "providerOrder": "scrapecreators-first",
    "includeRawData": False,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/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 '{
  "channelUrls": [
    "https://www.youtube.com/@MrBeast"
  ],
  "contentType": "videos",
  "maxVideosPerChannel": 10,
  "maxPagesPerContentType": 1,
  "maxTotalVideos": 10,
  "sortBy": "latest",
  "providerOrder": "scrapecreators-first",
  "includeRawData": false
}' |
apify call khadinakbar/youtube-channel-videos-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Channel Videos Scraper — Metadata & Metrics",
        "description": "Scrape public YouTube channel videos and Shorts with titles, descriptions, dates, views, likes, comments, duration, thumbnails, and channel metadata. No cookies required.",
        "version": "1.4",
        "x-build-id": "ihvINjL3ZuiMxA7zg"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/khadinakbar~youtube-channel-videos-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-khadinakbar-youtube-channel-videos-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/khadinakbar~youtube-channel-videos-scraper/runs": {
            "post": {
                "operationId": "runs-sync-khadinakbar-youtube-channel-videos-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/khadinakbar~youtube-channel-videos-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-khadinakbar-youtube-channel-videos-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "channelUrls"
                ],
                "properties": {
                    "channelUrls": {
                        "title": "YouTube Channels",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Use this when you want public videos from one or more known YouTube channels. Accepts channel URLs such as https://www.youtube.com/@MrBeast, a handle such as @MrBeast, or a channel ID beginning UC. The prefill is a public channel for a quick test. This is not for video URLs, playlists, keyword search, comments, or private channels.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "contentType": {
                        "title": "Content Type",
                        "enum": [
                            "videos",
                            "shorts",
                            "all"
                        ],
                        "type": "string",
                        "description": "Use this to choose which public channel feed to collect. Select videos for long-form videos, shorts for YouTube Shorts, or all to process both feeds. Defaults to videos for a focused and predictable run. This does not download video media or transcripts.",
                        "default": "videos"
                    },
                    "maxVideosPerChannel": {
                        "title": "Max Videos Per Channel",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Use this to cap how many normalized rows are saved for each channel across the selected content types. Accepts whole numbers from 1 to 500 and defaults to 50; the prefill is 10. This is the main per-channel billing and volume guard. It is not a request-page limit.",
                        "default": 50
                    },
                    "maxPagesPerContentType": {
                        "title": "Max Pages Per Content Type",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Use this to limit provider pagination for each channel's video or Shorts feed. Accepts whole numbers from 1 to 50 and defaults to 10; the prefill is 1 for a fast check. It protects against unexpectedly deep feeds. It is not a direct row-count limit.",
                        "default": 10
                    },
                    "maxTotalVideos": {
                        "title": "Max Total Videos",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Use this to cap all saved video and Short rows across the entire run. Accepts whole numbers from 1 to 5000 and defaults to 500; the prefill is 10. This is the strongest whole-run cost guard. It does not set an Apify platform-usage cap.",
                        "default": 500
                    },
                    "sortBy": {
                        "title": "Feed Sort Order",
                        "enum": [
                            "latest",
                            "popular"
                        ],
                        "type": "string",
                        "description": "Use this to request newest-first or popularity-oriented channel ordering from the provider. Accepted values are latest and popular, and the default is latest. Providers can differ slightly in their ranking and freshness. This is not a date filter.",
                        "default": "latest"
                    },
                    "publishedAfter": {
                        "title": "Published On or After",
                        "type": "string",
                        "description": "Use this to keep only records published on or after a UTC calendar date. Enter an ISO date such as 2025-01-01; omit it to keep every returned date. Rows with no machine-readable publish date are excluded while a date filter is active. This is not a relative date phrase such as last month."
                    },
                    "publishedBefore": {
                        "title": "Published Before",
                        "type": "string",
                        "description": "Use this to keep only records published before a UTC calendar date. Enter an ISO date such as 2025-12-31; omit it to keep every returned date. Rows with no machine-readable publish date are excluded while a date filter is active. This is not an inclusive end-of-day timestamp."
                    },
                    "providerOrder": {
                        "title": "Provider Order",
                        "enum": [
                            "scrapecreators-first",
                            "sociavault-first",
                            "scrapecreators-only",
                            "sociavault-only"
                        ],
                        "type": "string",
                        "description": "Use this to select the public-data provider route and fallback order. ScrapeCreators first is the default because its channel endpoint was probed with the normalized fields; SociaVault is the redundant fallback. Defaults to ScrapeCreators first. This option does not use browser automation, YouTube cookies, or a personal API key.",
                        "default": "scrapecreators-first"
                    },
                    "includeRawData": {
                        "title": "Include Raw Provider Data",
                        "type": "boolean",
                        "description": "Use this only when debugging provider field drift or building a custom parser. When enabled, the original provider item is attached to each dataset row and capped to keep records bounded. Defaults to false because raw payloads are not ideal for spreadsheets or AI-agent output. This does not return private YouTube data.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
