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

Collect public YouTube channel profiles from handles or URLs — subscribers, description, avatar, country, and channel stats. Optionally add videos and Shorts with views, likes, duration, and thumbnails. Output as separate dataset rows (channel, video, short) or one nested record per channel.

- **URL**: https://apify.com/calm\_builder/youtube-channel-scraper.md
- **Developed by:** [Coder](https://apify.com/calm_builder) (community)
- **Categories:** Videos, Developer tools, Social media
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.10 / 1,000 channel profile collecteds

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/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 Scraper

Collect structured data from public [YouTube](https://www.youtube.com) **channel** pages using handles or channel URLs. Add one or more channels, start a run, and receive clean JSON in your Apify dataset — no YouTube login required.

Use it for **creator research**, **competitive intelligence**, **influencer outreach**, **content monitoring**, **market research**, **lead enrichment**, and **automation workflows** — without copying channel profiles, video lists, or Shorts manually.

***

### What you get

Every run always collects **channel profile data** (subscribers, description, avatar, country, and more). You can optionally add **videos** from the channel’s Videos tab and **Shorts** from the Shorts tab.

| Section                   | What it contains                                                                                                 |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **Channel profile**       | Name, handle, URL, subscriber count, video count, total views, avatar, country, description, verification status |
| **`videos`** *(optional)* | Regular uploads with title, URL, publish date, duration, views, likes, comments, thumbnails                      |
| **`shorts`** *(optional)* | Short-form uploads with the same enriched fields                                                                 |
| **`summary`**             | How many videos and Shorts were requested vs collected                                                           |
| **`warnings`**            | User-friendly notes when part of a channel could not be loaded                                                   |

Results are saved to the dataset **as each channel is processed**, so you can preview progress before the run finishes.

***

### Quick start on Apify

1. Open the Actor in the Apify Console.
2. Under **Channel handles and links**, add one or more YouTube channels (one per line).
3. Choose your **output format** — separate dataset rows per channel / video / Short (default), or one row per channel with nested arrays.
4. Enable **Include channel videos** and/or **Include channel Shorts** if you need uploads, and set the per-channel limits.
5. Click **Start** and open the **Dataset** tab as results are saved.

**Supported input formats:**

- Handle: `@apify`
- Channel URL: `https://www.youtube.com/@apify`
- Legacy URLs: `https://www.youtube.com/channel/UC…`, `/c/…`, `/user/…`

**Example input:**

```json
{
  "channelInputs": ["@apify", "https://www.youtube.com/@apify"],
  "separateChannelRecords": true,
  "includeChannelVideos": true,
  "includeChannelShorts": true,
  "maxChannelVideos": 20,
  "maxChannelShorts": 20,
  "channelDateRangeSortBy": "latest",
  "channelDateRangeDate": ""
}
```

***

### Input parameters

#### Channel handles and links

|              |                                                                              |
| ------------ | ---------------------------------------------------------------------------- |
| **Field**    | `channelInputs`                                                              |
| **Type**     | List of text entries (one channel per line)                                  |
| **Required** | Yes — at least one entry                                                     |
| **Formats**  | `@handle`, `youtube.com/@handle`, `youtube.com/channel/…`, `/c/…`, `/user/…` |

Duplicate channels in the same run are processed once.

Unsupported entries are skipped with a log message.

#### Output format

| Field                    | Default | Description                                                                                                                                                                                                                                          |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `separateChannelRecords` | `true`  | When enabled, the dataset uses **separate rows** for each channel (`type: channel`), video (`type: video`), and Short (`type: short`). When disabled, you get **one row per channel** with optional `videos` and `shorts` arrays on the same object. |

#### Videos and Shorts (optional)

| Field                  | Default | Description                                                                          |
| ---------------------- | ------- | ------------------------------------------------------------------------------------ |
| `includeChannelVideos` | `false` | Collect items from the channel’s **Videos** tab                                      |
| `includeChannelShorts` | `false` | Collect items from the channel’s **Shorts** tab                                      |
| `maxChannelVideos`     | `10`    | Maximum videos per channel (1–2,000). Applies only when video collection is enabled  |
| `maxChannelShorts`     | `10`    | Maximum Shorts per channel (1–2,000). Applies only when Shorts collection is enabled |

The video and Short limits apply **independently per channel**. For example, 5 channels with `maxChannelVideos: 20` and `maxChannelShorts: 20` can return up to **100 videos** and **100 Shorts** in total (plus 5 channel profile rows when using separate records).

#### Sorting and date filter (videos only)

| Field                    | Default   | Description                                                                                                                                                                                                      |
| ------------------------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `channelDateRangeSortBy` | `latest`  | Order for tab results: `latest`, `popular`, or `oldest`                                                                                                                                                          |
| `channelDateRangeDate`   | *(empty)* | Optional publish-time filter for **videos only**. Use `YYYY-MM-DD` or relative values such as `2 weeks`, `3 months`, `1 year`. When set, sorting is automatically forced to **Latest**. Does not apply to Shorts |

***

### What you will see during a run

Messages describe collection progress and outcomes.

Typical messages:

- `Starting collection for N channel(s).`
- `Prepared 41 dataset item(s) for channel 1 of 2 (Apify).` when **Separate dataset records** is enabled
- `Prepared channel result 1 of 2 (Apify).` when results are nested on one row per channel
- `Collection finished with N dataset item(s).`
- `N unsupported channel input(s) will be skipped.`

If one channel cannot be fully loaded, other channels in the same run can still succeed. Check the **`status`** and **`warnings`** fields on each channel result.

On the Apify **free plan**, you may also see notices when free-tier limits apply (see [Free plan limits](#free-plan-limits)).

***

### Output overview

#### Dataset structure

Results are saved to a **single Apify dataset**.

**Separate records (default)** — filter by `type`:

| `type`    | One row represents                                    |
| --------- | ----------------------------------------------------- |
| `channel` | Channel profile + `summary` + optional `warnings`     |
| `video`   | One regular video, with parent channel context fields |
| `short`   | One Short, with parent channel context fields         |

**Nested records** (`separateChannelRecords: false`) — one row per input channel:

- Channel profile fields at the top level
- Optional `videos` and `shorts` arrays on the same object
- `summary` counts on the channel row

#### Status values

| `status`        | Meaning                                                      |
| --------------- | ------------------------------------------------------------ |
| `ok`            | Channel profile (and requested media) collected successfully |
| `partial`       | Channel or media collected with warnings — see `warnings`    |
| `failed`        | Channel could not be processed — see `error` or `warnings`   |
| `invalid_input` | Input was not a supported channel handle or URL              |

Field presence varies by channel. Not every channel publishes country, full descriptions, or complete stats on the public page. Missing optional fields are omitted from the output.

***

### Output fields

#### Channel record (`type: channel`, or nested mode)

| Field              | Description                                                                |
| ------------------ | -------------------------------------------------------------------------- |
| `type`             | `channel` (separate records mode only)                                     |
| `inputValue`       | Original input string for this channel                                     |
| `channelUrl`       | Normalized channel URL                                                     |
| `status`           | `ok`, `partial`, `failed`, or `invalid_input`                              |
| `error`            | Short explanation when collection failed or input was invalid              |
| `id`               | YouTube channel ID (`UC…`)                                                 |
| `name`             | Channel display name                                                       |
| `handle`           | Public handle (for example `@apify`)                                       |
| `url`              | Canonical channel URL                                                      |
| `isVerified`       | Whether the channel shows a verification badge                             |
| `subscriberCount`  | Subscriber count as a number when available                                |
| `videoCountText`   | Public video count label from YouTube                                      |
| `totalViewsText`   | Total channel views label when shown                                       |
| `avatarUrl`        | Channel avatar image URL                                                   |
| `country`          | Country code when published                                                |
| `description`      | Full channel description                                                   |
| `shortDescription` | Short description when available                                           |
| `sortBy`           | Sort applied when collecting videos or Shorts                              |
| `dateRange`        | Date filter applied to videos, if any                                      |
| `videos`           | Array of video objects *(nested mode only, when enabled)*                  |
| `shorts`           | Array of Short objects *(nested mode only, when enabled)*                  |
| `summary`          | `videosRequested`, `shortsRequested`, `videosCollected`, `shortsCollected` |
| `warnings`         | List of user-friendly warning messages                                     |
| `collectedAt`      | ISO timestamp when the record was saved                                    |

#### Video / Short record (`type: video` or `type: short`)

| Field             | Description                                         |
| ----------------- | --------------------------------------------------- |
| `type`            | `video` or `short`                                  |
| `inputValue`      | Original channel input                              |
| `channelUrl`      | Parent channel URL                                  |
| `channelId`       | Parent channel ID                                   |
| `channelName`     | Parent channel name                                 |
| `channelHandle`   | Parent channel handle                               |
| `id`              | Video or Short ID                                   |
| `url`             | Watch or Shorts URL                                 |
| `title`           | Title                                               |
| `description`     | Description when available                          |
| `publishedDate`   | ISO publish timestamp                               |
| `durationSeconds` | Duration in seconds                                 |
| `viewCount`       | View count                                          |
| `likeCount`       | Like count when available                           |
| `commentCount`    | Comment count when available                        |
| `thumbnailUrl`    | Primary thumbnail URL                               |
| `thumbnails`      | Array of thumbnail sizes (`url`, `width`, `height`) |
| `isLive`          | Whether the item is live content                    |
| `isUpcoming`      | Whether the item is an upcoming premiere            |
| `collectedAt`     | ISO timestamp when the record was saved             |

#### Nested `videos` / `shorts` array items

Same fields as the video / Short rows above, **without** the `type` and parent channel context fields (those live on the parent channel object).

***

### Example output

The excerpts below are from real runs against public YouTube channels. Your run dataset will contain the full records.

#### Example input

```json
{
  "channelInputs": ["https://www.youtube.com/@apify"],
  "separateChannelRecords": true,
  "includeChannelVideos": true,
  "includeChannelShorts": true,
  "maxChannelVideos": 20,
  "maxChannelShorts": 20
}
```

#### Excerpt — separate records: channel row

When **Separate dataset records** is enabled (`separateChannelRecords: true`):

```json
{
  "inputValue": "https://www.youtube.com/@apify",
  "channelUrl": "https://www.youtube.com/@apify",
  "status": "ok",
  "sortBy": "latest",
  "summary": {
    "videosRequested": 20,
    "shortsRequested": 20,
    "videosCollected": 20,
    "shortsCollected": 20
  },
  "collectedAt": "2026-06-29T17:59:37+00:00",
  "id": "UCTgwcoeGGKmZ3zzCXN2qo_A",
  "name": "Apify",
  "handle": "@apify",
  "url": "https://www.youtube.com/@apify",
  "isVerified": true,
  "subscriberCount": 14400,
  "videoCountText": "255",
  "totalViewsText": "9989847",
  "avatarUrl": "https://yt3.ggpht.com/taqvhsquq1iG09A82lJy_qSjXUmvQB0Tm-kAPIxgg0pv1fqSwvZ7ZNWhkWZ1Ias1_mZrllnNsQ4=s800-c-k-c0x00ffffff-no-rj",
  "country": "CZ",
  "description": "Welcome to Apify’s official YouTube channel! Apify is a web scraping and automation platform...",
  "shortDescription": "Welcome to Apify’s official YouTube channel! Apify is a web scraping and automation platform...",
  "type": "channel"
}
```

#### Excerpt — separate records: video row

```json
{
  "type": "video",
  "collectedAt": "2026-06-29T17:59:37+00:00",
  "inputValue": "https://www.youtube.com/@apify",
  "channelUrl": "https://www.youtube.com/@apify",
  "channelId": "UCTgwcoeGGKmZ3zzCXN2qo_A",
  "channelName": "Apify",
  "channelHandle": "@apify",
  "id": "faf4ouwGykc",
  "url": "https://www.youtube.com/watch?v=faf4ouwGykc",
  "title": "I Scraped 90 YouTube Videos to See What's Actually Winning",
  "publishedDate": "2026-06-17T17:00:22Z",
  "durationSeconds": 230,
  "viewCount": 332,
  "likeCount": 15,
  "commentCount": 1,
  "thumbnailUrl": "https://i.ytimg.com/vi/faf4ouwGykc/maxresdefault.jpg",
  "isLive": false,
  "isUpcoming": false
}
```

#### Excerpt — separate records: Short row

```json
{
  "type": "short",
  "collectedAt": "2026-06-29T17:59:37+00:00",
  "inputValue": "https://www.youtube.com/@apify",
  "channelUrl": "https://www.youtube.com/@apify",
  "channelId": "UCTgwcoeGGKmZ3zzCXN2qo_A",
  "channelName": "Apify",
  "channelHandle": "@apify",
  "id": "LUTaRsyFzno",
  "url": "https://www.youtube.com/shorts/LUTaRsyFzno",
  "title": "Watch Klára’s full presentation on our channel! 🏠📈 #apify #praguecrawl #dev",
  "publishedDate": "2026-06-24T11:44:01Z",
  "durationSeconds": 53,
  "viewCount": 877,
  "likeCount": 7,
  "commentCount": 0,
  "thumbnailUrl": "https://i.ytimg.com/vi/LUTaRsyFzno/maxresdefault.jpg",
  "isLive": false,
  "isUpcoming": false
}
```

#### Excerpt — nested single record per channel

When **Separate dataset records** is disabled (`separateChannelRecords: false`), each channel is one dataset row with optional `videos` and `shorts` arrays:

```json
{
  "inputValue": "https://www.youtube.com/@apify",
  "channelUrl": "https://www.youtube.com/@apify",
  "status": "ok",
  "sortBy": "latest",
  "videos": [
    {
      "id": "faf4ouwGykc",
      "url": "https://www.youtube.com/watch?v=faf4ouwGykc",
      "title": "I Scraped 90 YouTube Videos to See What's Actually Winning",
      "publishedDate": "2026-06-17T17:00:22Z",
      "durationSeconds": 230,
      "viewCount": 332,
      "likeCount": 15,
      "commentCount": 1,
      "thumbnailUrl": "https://i.ytimg.com/vi/faf4ouwGykc/maxresdefault.jpg",
      "isLive": false,
      "isUpcoming": false
    }
  ],
  "shorts": [
    {
      "id": "LUTaRsyFzno",
      "url": "https://www.youtube.com/shorts/LUTaRsyFzno",
      "title": "Watch Klára’s full presentation on our channel! 🏠📈 #apify #praguecrawl #dev",
      "publishedDate": "2026-06-24T11:44:01Z",
      "durationSeconds": 53,
      "viewCount": 877,
      "likeCount": 7,
      "commentCount": 0,
      "thumbnailUrl": "https://i.ytimg.com/vi/LUTaRsyFzno/maxresdefault.jpg",
      "isLive": false,
      "isUpcoming": false
    }
  ],
  "summary": {
    "videosRequested": 20,
    "shortsRequested": 20,
    "videosCollected": 20,
    "shortsCollected": 20
  },
  "collectedAt": "2026-06-29T17:52:34+00:00",
  "id": "UCTgwcoeGGKmZ3zzCXN2qo_A",
  "name": "Apify",
  "handle": "@apify",
  "url": "https://www.youtube.com/@apify",
  "isVerified": true,
  "subscriberCount": 14400,
  "videoCountText": "255",
  "totalViewsText": "9989847",
  "country": "CZ"
}
```

#### Excerpt — invalid input

```json
{
  "inputValue": "not-a-channel",
  "status": "invalid_input",
  "error": "This input is not a supported YouTube channel handle or URL.",
  "type": "channel"
}
```

When `status` is `invalid_input` or `failed`, rely on **`error`** and **`warnings`** for context. Partial channel data may still be present when `status` is `partial`.

***

### Pricing

This Actor uses **pay-per-event** pricing. You are charged only for **successful** collection — failed or invalid channels are not billed for channel events, and only successfully collected videos and Shorts count toward media events.

| Event                       | When it is charged                                                                                  |
| --------------------------- | --------------------------------------------------------------------------------------------------- |
| **`channel_record`**        | Once per channel **successfully saved** (`status` is `ok` or `partial`)                             |
| **`channel_videos_shorts`** | Once per **video or Short successfully collected** when the corresponding tab collection is enabled |

**Examples** (see the **Pricing** tab on the Store listing for current rates):

| Run                                             | What you pay for                                           |
| ----------------------------------------------- | ---------------------------------------------------------- |
| 10 channels, videos and Shorts disabled         | 10 `channel_record` events                                 |
| 1 channel + 20 videos + 20 Shorts, all succeed  | 1 `channel_record` + 40 `channel_videos_shorts` events     |
| 5 channels + 100 videos each, all succeed       | 5 `channel_record` + 500 `channel_videos_shorts` events    |
| 10 channels requested, 2 invalid inputs skipped | 8 `channel_record` events (invalid inputs are not charged) |

Disable **Include channel videos** and **Include channel Shorts** if you only need profile data — you will not be charged for `channel_videos_shorts` events.

When **Separate dataset records** is enabled, the dataset lists each channel, video, and Short as its own row. Billing still uses the two events above: one charge per channel saved, and one charge per video or Short collected.

***

### Free plan limits

On the Apify **free plan**, the Actor may automatically apply:

| Limit                      | Value                                        |
| -------------------------- | -------------------------------------------- |
| Channels processed per run | **10** (only the first entries in your list) |
| Maximum videos per channel | **5** (when video collection is enabled)     |
| Maximum Shorts per channel | **5** (when Shorts collection is enabled)    |

Additional channels in the same run are not processed. Paid Apify plans can use the full input list and higher per-channel limits without these caps. If limits apply, the run log will include a short notice.

***

### Public data and coverage

**No YouTube login required**\
The Actor reads publicly visible channel pages. It does not sign in to YouTube and does not use your Google account.

**Guest view vs signed-in view**\
Results reflect what YouTube shows to visitors who are not logged in. Compared with a signed-in session, output may differ slightly in counts, ordering, or available metadata.

**Videos and Shorts**\
Collection reads the channel’s public Videos and Shorts tabs up to your limits. The number returned depends on what YouTube exposes and on your sort / date filter settings. The date filter applies to **videos only**, not Shorts.

**Unavailable or restricted channels**\
Some channels may return `partial` or `failed` with a message in `warnings` or `error`. Retrying later or processing a smaller batch can help in some cases.

**Compliance**\
You are responsible for using collected data in line with applicable laws and [YouTube's Terms of Service](https://www.youtube.com/t/terms).

***

### Tips for best results

1. **Use handles or full URLs** — Both `@apify` and `https://www.youtube.com/@apify` work.
2. **Start with a small batch** — Test with 2–5 channels before large exports.
3. **Pick the right output format** — Use **separate records** (default) for spreadsheets, warehouses, and filtering by `type`. Use **nested records** when you want one JSON object per channel.
4. **Enable only what you need** — Profile-only runs are faster and cost less than full video + Shorts collection.
5. **Set sensible limits** — Use lower `maxChannelVideos` / `maxChannelShorts` for quick checks; raise them for catalog builds.
6. **Filter on `status`** — Use `ok` and `partial` for usable data; review `warnings` on partial rows.
7. **Deduplicate on channel `id`** — The `UC…` channel ID is a stable key across runs.
8. **Schedule recurring runs** — Use Apify schedules to refresh channel stats and latest uploads for your target list.
9. **Export flexibly** — Download as JSON, CSV, Excel, or connect via API to your BI tools, CRM, or automation stack.

***

### Frequently asked questions

**Can I scrape multiple channels in one run?**\
Yes. Add as many handles or URLs as you need (subject to free-plan caps on the Apify free tier).

**What is the difference between separate and nested output?**\
**Separate records** (default) writes one dataset row per channel, video, and Short, each with a `type` field. **Nested records** writes one row per channel with `videos` and `shorts` arrays on the same object.

**Do I always get channel profile data?**\
Yes. Every supported channel input produces channel profile fields. Videos and Shorts are optional.

**Why are there fewer videos than my `maxChannelVideos` setting?**\
YouTube may expose fewer items than your limit, or a tab may not load fully. Check `summary.videosCollected` and `warnings` on the channel row.

**Why is `status` `partial`?**\
Some part of the channel run had an issue — for example the Videos tab could not be loaded but the profile was retrieved. Read `warnings` for details.

**Does the date filter apply to Shorts?**\
No. `channelDateRangeDate` filters **videos only**.

**Can I sort videos by most popular?**\
Yes. Set `channelDateRangeSortBy` to `popular` or `oldest`. If a date range is set, sorting is forced to **Latest**.

**Will failed channels be charged?**\
No. `channel_record` is charged only for successfully saved channels (`ok` or `partial`). Media events are charged only for videos and Shorts that were actually collected.

**Can I get live stream or premiere metadata?**\
Video and Short items include `isLive` and `isUpcoming` when YouTube provides that information.

**Does this Actor download video files?**\
No. It returns metadata and URLs only — not MP4 files or audio.

***

### Support

For Actor-specific issues, use the **Issues** tab on the Apify Store listing or contact the publisher through Apify.

For platform questions (runs, billing, API, schedules), see [Apify documentation](https://docs.apify.com) and Apify support.

# Actor input Schema

## `channelInputs` (type: `array`):

Add one channel per row. Supported values: handles such as `@apify` and full YouTube channel URLs. Channel profile data is always collected for every row.

## `separateChannelRecords` (type: `boolean`):

When enabled (default), the dataset contains separate items for each channel (`type: channel`), each video (`type: video`), and each Short (`type: short`). When disabled, one item per channel is returned with optional `videos` and `shorts` arrays on the same record.

## `includeChannelVideos` (type: `boolean`):

Collect items from the channel's Videos tab. With separate records enabled, each video is a dataset item with `type: video`. Otherwise, videos are returned in the `videos` array on the channel record.

## `includeChannelShorts` (type: `boolean`):

Collect items from the channel's Shorts tab. With separate records enabled, each Short is a dataset item with `type: short`. Otherwise, Shorts are returned in the `shorts` array on the channel record.

## `maxChannelVideos` (type: `integer`):

Maximum number of regular videos to collect from each channel when `Include channel videos` is enabled.

## `maxChannelShorts` (type: `integer`):

Maximum number of Shorts to collect from each channel when `Include channel Shorts` is enabled.

## `channelDateRangeSortBy` (type: `string`):

Choose how channel tab results should be ordered when collecting videos or Shorts. If a channel date range is set, sorting is automatically forced to Latest.

## `channelDateRangeDate` (type: `string`):

Optional publish-time filter for channel videos when video collection is enabled. Use either an absolute date (`YYYY-MM-DD`) or a relative value such as `2 weeks`, `3 months`, or `1 year`. If set, channel sorting is automatically changed to Latest. This filter does not apply to Shorts. Leave empty to skip this filter.

## Actor input object example

```json
{
  "channelInputs": [
    "@MrBeast",
    "https://www.youtube.com/@apify"
  ],
  "separateChannelRecords": true,
  "includeChannelVideos": false,
  "includeChannelShorts": false,
  "maxChannelVideos": 10,
  "maxChannelShorts": 10,
  "channelDateRangeSortBy": "latest",
  "channelDateRangeDate": ""
}
```

# Actor output Schema

## `channels` (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 = {
    "channelInputs": [
        "@MrBeast",
        "https://www.youtube.com/@apify"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("calm_builder/youtube-channel-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "channelInputs": [
        "@MrBeast",
        "https://www.youtube.com/@apify",
    ] }

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/XM4WSb13CUhyZijAb/builds/kqAODnp4cznk8va5a/openapi.json
