# YouTube Channel & Search Scraper — Videos, Shorts, No API Key (`cycha/youtube-channel-scraper`) Actor

List every video and Short of a YouTube channel with views, duration, publish date and channel stats, or scrape YouTube search results. No API key, no quota, no login, no proxies.

- **URL**: https://apify.com/cycha/youtube-channel-scraper.md
- **Developed by:** [Ken Digital](https://apify.com/cycha) (community)
- **Categories:** Lead generation
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 videos

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Channel & Search Scraper — Videos, Shorts, Stats, No API Key

List every video and Short a channel has published, with views, duration, publish date and channel stats on each row, or pull YouTube search results in YouTube's own order. It reads the same internal endpoints the youtube.com page uses, so there is no API key, no daily quota, no login and no proxy to set up. A 500-video channel takes about half a minute on 256 MB of memory.

> **New name:** this actor is now `cycha/youtube-channel-scraper` (it was `joyouscam35875/youtube-channel-scraper` until 21 October 2026). If an API call or integration stopped working, update the name, or use the actor ID `n1skvO8Q6bYfYeyDK`, which never changes.

- **Channels by handle, URL or ID.** `@veritasium`, `youtube.com/@veritasium`, `youtube.com/channel/UC...`, `/c/...`, `/user/...` all work.
- **Whole back catalog.** Set the per-channel limit to `0` to walk every page.
- **Shorts tab on demand.** `includeShorts` adds the channel's Shorts, up to the same per-channel limit.
- **Search.** Any query, paged as far as you like, with channel, views, duration and description snippet.
- **Channel stats.** One channel row per channel: subscribers, video count, description, keywords, avatar, RSS feed.
- **Pay per video row.** Channel rows and error rows are free.

### Quick start

```json
{
  "channels": ["@veritasium", "https://www.youtube.com/@mkbhd"],
  "maxVideosPerChannel": 100,
  "includeShorts": true,
  "searchQueries": ["openclaw ai assistant"],
  "maxResultsPerQuery": 40
}
```

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `channels` | array | | Handles, channel URLs or `UC...` IDs. |
| `maxVideosPerChannel` | integer | 50 | Newest first. `0` = whole channel. |
| `includeShorts` | boolean | false | Also list the Shorts tab. The per-channel limit applies to each tab separately. |
| `searchQueries` | array | | YouTube search terms. |
| `maxResultsPerQuery` | integer | 50 | `0` = keep paging until YouTube stops. |
| `language` | string | `en` | Interface language (`hl`). Changes relative dates and search ranking. |
| `country` | string | `US` | Country (`gl`) for search ranking. |

At least one of `channels` or `searchQueries` is required.

### Output

Channel row:

```json
{
  "type": "channel",
  "channelId": "UCHnyfMqiRRG1u-2MsSQLbXA",
  "channelTitle": "Veritasium",
  "channelHandle": "@veritasium",
  "channelUrl": "https://www.youtube.com/channel/UCHnyfMqiRRG1u-2MsSQLbXA",
  "channelDescription": "An element of truth - videos about science, education, and anything else we find interesting.",
  "channelKeywords": "\"science videos\" science \"science education\"",
  "channelAvatar": "https://yt3.googleusercontent.com/...",
  "channelSubscribers": 21300000,
  "channelSubscribersText": "21.3M subscribers",
  "channelVideoCount": 535,
  "channelRssUrl": "https://www.youtube.com/feeds/videos.xml?channel_id=UCHnyfMqiRRG1u-2MsSQLbXA",
  "source": "channel:@veritasium",
  "scrapedAt": "2026-09-21T20:00:00+00:00"
}
```

Video row (from a channel or a search):

```json
{
  "type": "video",
  "videoId": "JsBZOcqZerk",
  "url": "https://www.youtube.com/watch?v=JsBZOcqZerk",
  "title": "The Machine that cracked the Nazis' \"Unbreakable\" Code",
  "viewCount": 130000,
  "viewCountText": "130K views",
  "publishedTimeText": "2 hours ago",
  "durationSeconds": 2862,
  "durationText": "47:42",
  "thumbnail": "https://i.ytimg.com/vi/JsBZOcqZerk/hq720.jpg",
  "isShort": false,
  "descriptionSnippet": null,
  "badges": [],
  "channelId": "UCHnyfMqiRRG1u-2MsSQLbXA",
  "channelTitle": "Veritasium",
  "channelHandle": "@veritasium",
  "channelUrl": "https://www.youtube.com/channel/UCHnyfMqiRRG1u-2MsSQLbXA",
  "channelSubscribers": 21300000,
  "source": "channel:@veritasium",
  "scrapedAt": "2026-09-21T20:00:00+00:00"
}
```

View counts and subscriber counts are parsed from YouTube's abbreviated figures ("130K", "21.3M"), so they carry YouTube's own rounding; search results usually carry exact counts. Publish dates are the relative text YouTube shows in listings. For per-video likes, exact views, full descriptions and comments, pass the video URLs to the [YouTube Comments Scraper](https://apify.com/cycha/youtube-comments-scraper).

### Pricing

Pay per event: one `video` event per video row, plus a tiny actor-start fee. Channel rows and error rows are free.

### Use cases

- Channel audits and competitor tracking: full upload history with views and cadence
- Content research: what a niche's channels publish, how long, how often
- Building datasets of video IDs for downstream analysis (transcripts, comments)
- Monitoring search results for a keyword over time

### Integrations

Run it from the Apify API, the JavaScript or Python client, the CLI, schedules, or as an MCP tool. Export to JSON, CSV, Excel, or push to Google Sheets, Make, Zapier or n8n.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("cycha/youtube-channel-scraper").call(run_input={
    "channels": ["@veritasium"],
    "maxVideosPerChannel": 0,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["type"] == "video":
        print(row["publishedTimeText"], row["viewCount"], row["title"])
```

### FAQ

**Why no API key?** The YouTube Data API caps you at 10,000 units a day and a channel listing burns through it fast. This actor reads the public page data instead, with no quota.

**Does it get exact view counts?** Channel listings show YouTube's abbreviated counts. Search results are usually exact. For exact per-video numbers, use the comments scraper linked above on the video URLs.

**Members-only or unlisted videos?** No. Only what a logged-out visitor sees.

**Is it legal?** The actor reads publicly visible data. You are responsible for how you use it and for complying with YouTube's terms and local law.

### Feedback

Missing a field, hit a bug, or need an input this actor doesn't take yet? Open an issue on the actor's **Issues** tab. If the YouTube Channel & Search Scraper saved you time, a short review on the Store page helps other people find it.

### Related actors by the same developer

| Actor | What it does |
|---|---|
| [YouTube Transcript Scraper](https://apify.com/cycha/youtube-transcript-scraper) | Transcripts of videos, playlists and whole channels, for AI |
| [YouTube Comments Scraper](https://apify.com/cycha/youtube-comments-scraper) | Comments and replies with video stats |
| [TikTok Scraper](https://apify.com/cycha/tiktok-scraper) | Videos, profiles and comments, no login |
| [Google Trends Scraper](https://apify.com/cycha/google-trends-scraper) | Interest over time, related queries and regions for up to 500 keywords |
| [Google News & RSS Scraper](https://apify.com/cycha/rss-news-aggregator) | Articles by keyword, language and country, or from any feed |

# Actor input Schema

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

Channel handles (@veritasium), channel URLs, or channel IDs (UC...). One channel row plus one row per video.

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

Newest first. 0 = the whole channel.

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

Also list the channel's Shorts tab. The per-channel limit applies to each tab separately.

## `searchQueries` (type: `array`):

Optional. YouTube search terms; returns video results in YouTube's order with channel, views, duration and description snippet.

## `maxResultsPerQuery` (type: `integer`):

0 = keep paging until YouTube stops.

## `language` (type: `string`):

Affects relative dates such as "2 days ago" and search ranking.

## `country` (type: `string`):

Country code for search ranking, e.g. US, FR, DE.

## Actor input object example

```json
{
  "channels": [
    "@veritasium"
  ],
  "maxVideosPerChannel": 50,
  "includeShorts": false,
  "searchQueries": [],
  "maxResultsPerQuery": 50,
  "language": "en",
  "country": "US"
}
```

# Actor output Schema

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

One channel row (type=channel) per channel and one row per video (type=video), from channels or searches.

# 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": [
        "@veritasium"
    ],
    "searchQueries": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("cycha/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 = {
    "channels": ["@veritasium"],
    "searchQueries": [],
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "channels": [
    "@veritasium"
  ],
  "searchQueries": []
}' |
apify call cycha/youtube-channel-scraper --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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