# Youtube Profile & Channel List Scraper (`transcriptdl/youtube-profile-channel-list-scraper`) Actor

Bulk extract YouTube channel profiles & video lists. Scrape subscriber counts, metadata & transcripts using Transcript Downloader API. Perfect for competitor analysis, content research & market intelligence.

- **URL**: https://apify.com/transcriptdl/youtube-profile-channel-list-scraper.md
- **Developed by:** [Transcript Downloader](https://apify.com/transcriptdl) (community)
- **Categories:** Social media, AI, Automation
- **Stats:** 35 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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 Profile & Channel List Scraper

Verified 99.4% Success Rate. Extract YouTube channel profiles & video lists. Scrape subscriber counts, metadata & transcripts using Transcript Downloader API. Perfect for competitor analysis, content research & market intelligence.

***

### ✨ Features

- 🏢 **Channel profile extraction**: Get channel metadata, subscriber count, total views, and creation date
- 📋 **Complete video lists**: Extract all videos from a channel with basic metadata
- 📊 **Optional detailed metadata**: Fetch full transcripts and metadata for individual videos
- 🔁 **Batch processing**: Handle multiple channels simultaneously
- ⚙️ **Concurrency control**: Adjust processing speed with configurable limits
- 🔄 **Automatic retries**: Handles API errors and retryable failures
- 🔔 **Webhook support**: Receive results via webhook instead of polling
- 🚦 **Rate limiting**: Built-in delays to respect API limits
- 💰 **Cost tracking**: Monitor API usage and costs per channel
- 🧠 **Error tracking**: All failures logged with detailed error information

***

### 🔧 Input Parameters

The actor accepts the following input:

| Parameter             | Type    | Required | Default | Description                                                       |
| --------------------- | ------- | -------- | ------- | ----------------------------------------------------------------- |
| `channelUrls`         | array   | ✅ Yes    | -       | List of YouTube channel URLs (supports @username and /channel/)   |
| `apiToken`            | string  | ✅ Yes    | -       | Your Transcript Downloader API bearer token                       |
| `includeVideoDetails` | boolean | No       | `false` | Whether to fetch complete metadata for each video                |
| `includeComments`     | boolean | No       | `false` | Whether to fetch comments (only shown when includeVideoDetails=true) |
| `maxConcurrency`      | number  | No       | `2`     | Max concurrent channel requests (range: 1-5)                     |
| `videoLimit`          | number  | No       | `50`    | Max videos to process per channel when includeVideoDetails=true  |
| `includeWebhook`      | string  | No       | -       | Webhook URL to receive results when channel processing completes. Must be publicly reachable and accept POST requests |

#### 📥 Sample Input

```json
{
  "channelUrls": [
    "https://www.youtube.com/@google",
    "https://www.youtube.com/channel/UCK8sQmJBp8GCxrOtXWBpyEA"
  ],
  "apiToken": "your-api-token",
  "includeVideoDetails": false,
  "includeComments": false,
  "maxConcurrency": 2,
  "videoLimit": 50
}
```

***

### 📤 Output Format

Each channel will produce a dataset item with the following structure:

#### Basic Channel Profile Output

```json
{
  "channelUrl": "https://www.youtube.com/@google",
  "profile": {
    "youtube_id": "UCK8sQmJBp8GCxrOtXWBpyEA",
    "title": "Google",
    "url": "https://www.youtube.com/@google",
    "thumbnail": "https://yt3.ggpht.com/...",
    "description": "Channel description...",
    "total_media": 1234,
    "subscriber_count": 5000000,
    "total_views": 100000000,
    "country": "US",
    "creation_date": "2005-02-14 23:41:51"
  },
  "videos": [
    {
      "youtube_id": "abc123",
      "title": "Video Title",
      "thumbnail": "https://i.ytimg.com/vi/abc123/default.jpg",
      "published_at": "2024-01-01 12:00:00",
      "duration": 300
    }
  ],
  "summary": {
    "totalVideos": 1234,
    "videosInResponse": 1234,
    "videosWithDetails": 0,
    "totalCost": "0.500",
    "processingTime": "15.2s"
  },
  "downloadInfo": {
    "id": "01K31YQ38SNP30F7218NX4SMN7",
    "type": "list",
    "cost": "0.500",
    "status": "success",
    "created_at": "2025-01-23T20:01:17.000000Z"
  }
}
```

#### With Detailed Video Metadata

When `includeVideoDetails: true`, each video will include additional metadata:

```json
{
  "youtube_id": "abc123",
  "title": "Video Title",
  "thumbnail": "https://i.ytimg.com/vi/abc123/default.jpg",
  "published_at": "2024-01-01 12:00:00",
  "duration": 300,
  "detailedMetadata": {
    "description": "Full video description...",
    "viewCount": 100000,
    "likeCount": 5000,
    "commentCount": 250,
    "channelName": "Channel Name",
    "channelUrl": "https://www.youtube.com/channel/...",
    "fullTranscript": "Complete video transcript...",
    "transcriptsWithTimeStamps": [
      {
        "start": "0.0",
        "dur": "3.5",
        "text": "Welcome to this video..."
      }
    ],
    "comments": {
      "mostRelevant": [
        {
          "author": "User123",
          "text": "This helped me so much!"
        }
      ],
      "mostRecent": [
        {
          "author": "User456", 
          "text": "Just watched it!"
        }
      ]
    }
  }
}
```

**Note**: The `comments` field only appears when both `includeVideoDetails: true` and `includeComments: true`.

***

### 🚀 How to Use

1. **Get your API token** from [Transcript Downloader](https://dashboard.transcriptdownloader.com/settings)
2. **Add channel URLs** in supported formats:
   - `https://www.youtube.com/@username`
   - `https://www.youtube.com/channel/CHANNEL_ID`
   - `https://www.youtube.com/c/channelname`
   - `https://www.youtube.com/user/username`
3. **Configure options** based on your needs:
   - Set `includeVideoDetails: false` for basic channel info (faster, cheaper)
   - Set `includeVideoDetails: true` for complete video metadata (slower, more expensive)
4. **Run the actor** and access results in the dataset

***

### ❌ Error Handling

The actor gracefully handles common API errors:

| Status Code | Meaning                                      | Action                           |
| ----------- | -------------------------------------------- | -------------------------------- |
| 400         | Invalid channel URL or channel restricted   | Check URL format and availability |
| 401         | Insufficient credits or invalid token       | Check credits and API token       |
| 403         | Invalid API token                           | Regenerate API token              |
| 429         | Rate limit exceeded                         | Actor handles with delays         |
| 503         | Service temporarily unavailable             | Retry automatically               |

Failed channels are captured in the dataset with error information:

```json
{
  "channelUrl": "https://www.youtube.com/@invalid",
  "error": "Invalid channel URL or channel restricted",
  "status": "failed"
}
```

***

***

### 💳 Pricing & Billing

The Transcript Downloader API used by this actor requires a valid API token. API usage is billed separately and is based on processing time and file size.

📊 We charge on a per transcript/metadata basis. Visit our site to checkout pricing. View full details and subscription plans on our [pricing page](https://transcriptdownloader.com/#pricing)

***

### ⚠️ Rate Limiting & Performance

#### API Rate Limits

| Scope | Limit | Window |
| ----- | ----- | ------ |
| Per User (API Token) | 90 requests | 1 minute |
| Per IP (unauthenticated) | 90 requests | 1 minute |

When rate limits are exceeded, the API returns `429 Too Many Requests`. The actor handles this automatically with built-in retry logic.

#### YouTube API Quotas

YouTube API access is subject to daily quota limits to comply with YouTube's terms of service.

| Operation | Quota Units | Notes |
| --------- | ----------- | ----- |
| Channel Profile Fetch | 1 unit | Initial channel lookup |
| Video List (per 50 videos) | 2 units | Pagination uses additional quota |
| Video Metadata | 1 unit | Per video info request |

Daily quota is configurable per account and resets automatically at **midnight UTC**. When quota is exhausted, the API returns a `429` error until reset.

#### Processing Times

| Scenario | Typical Duration |
| -------- | ---------------- |
| Basic profile (no video details) | ~5-15 seconds per channel |
| With video details | ~1-2 minutes per video |
| Large channels (1000+ videos, list only) | ~30-60 seconds |

#### Retry Behavior

The actor automatically retries on transient errors (429, 500, 503) with exponential backoff (base delay 1s, max delay 60s, up to 5 attempts). It does **not** retry on client errors (401, 403, 404) since those require user action.

#### Response Headers

The API returns rate limit headers you can monitor in logs:

| Header | Description |
| ------ | ----------- |
| `X-RateLimit-Limit` | Max requests allowed in window |
| `X-RateLimit-Remaining` | Requests remaining in current window |
| `Retry-After` | Seconds to wait before retrying (on 429) |

***

### 🔔 Webhook Support

Instead of waiting for channel processing to complete, you can receive results automatically via webhook. Pass a publicly reachable URL in the `includeWebhook` field, and the API will POST the results directly to your server when processing completes.

#### How It Works

1. The webhook URL is sent with the **channel profile request only** (not with individual video detail fetches)
2. One webhook is fired per channel when the profile & video list completes or fails
3. The webhook payload is the exact same JSON the API endpoint would return
4. Failed deliveries are retried up to 3 times (at 10s, 30s, and 60s intervals)

#### Webhook Headers

Each delivery includes these custom headers to identify the event:

| Header | Description |
| ------ | ----------- |
| `X-Webhook-Endpoint` | `channel/videos` |
| `X-Webhook-Original-Status` | HTTP status code of the result (e.g. `200`) |
| `X-Webhook-Download-Id` | The download record ID |

#### Example with Webhook

```json
{
  "channelUrls": ["https://www.youtube.com/@google"],
  "apiToken": "your-token",
  "includeWebhook": "https://your-domain.com/webhook"
}
```

> **Tip**: The webhook delivers the channel profile and video list data. If you also have `includeVideoDetails: true`, the actor still processes those sequentially after the initial profile fetch.

#### Important Notes

- The URL must be publicly reachable (no localhost or private IPs)
- Your endpoint must accept **POST** requests and return a `2xx` status
- Test your webhook URL first using the [API test endpoint](https://documentation.transcriptdownloader.com)
- The webhook is registered once at request time — it cannot be added after a job has started

***

### 💡 Best Practices

#### For Basic Channel Analysis

```json
{
  "channelUrls": ["https://www.youtube.com/@channel1", "https://www.youtube.com/@channel2"],
  "apiToken": "your-token",
  "includeVideoDetails": false,
  "maxConcurrency": 3
}
```

#### For Detailed Content Analysis

```json
{
  "channelUrls": ["https://www.youtube.com/@channel"],
  "apiToken": "your-token", 
  "includeVideoDetails": true,
  "includeComments": true,
  "maxConcurrency": 1,
  "videoLimit": 10
}
```

#### With Webhook

```json
{
  "channelUrls": ["https://www.youtube.com/@channel"],
  "apiToken": "your-token",
  "includeWebhook": "https://your-domain.com/webhook"
}
```

**Use case**: Receive channel profile & video list data at your server automatically

#### General Tips

- ✅ Start with `includeVideoDetails: false` to explore channels
- ✅ Use `videoLimit` to control costs when getting video details
- ✅ Enable `includeComments: true` only when you need comment analysis (requires video details)
- ✅ Use `includeWebhook` to receive results without waiting for the actor to finish
- ✅ Keep `maxConcurrency` low (1-2) to avoid rate limits
- ✅ Monitor costs using the `summary.totalCost` field
- ✅ Monitor daily YouTube API quota usage in your dashboard
- ✅ Validate channel URLs before running large batches

***

### 🔗 Supported URL Formats

The actor supports all major YouTube channel URL formats:

```
✅ https://www.youtube.com/@username
✅ https://www.youtube.com/channel/UCxxxxxxxxxxxxxxxxxx
✅ https://www.youtube.com/c/channelname
✅ https://www.youtube.com/user/username
✅ http://www.youtube.com/@username (HTTP also supported)
```

***

### 📈 Monitoring & Analytics

Track your usage with the built-in summary data:

```json
{
  "summary": {
    "totalVideos": 1234,
    "videosInResponse": 1234,
    "videosWithDetails": 50,
    "totalCost": "0.500",
    "processingTime": "45.2s"
  }
}
```

Use this data to:

- Monitor API costs per channel
- Track processing performance
- Plan batch processing strategies
- Optimize concurrency settings

***

### 🙋 Support

Need help? Visit [Transcript Downloader Support](https://www.transcriptdownloader.com/#contact).
We respond within 24 business hours.

For technical issues with this actor, check the run logs for detailed error messages.

***

### 📄 License

This actor is provided under the [ISC License](https://opensource.org/licenses/ISC).

# Actor input Schema

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

List of YouTube channel URLs to process. Supports both @username and /channel/ formats.

## `apiToken` (type: `string`):

Your Transcript Downloader API bearer token. Get it from your dashboard at https://dashboard.transcriptdownloader.com

## `includeVideoDetails` (type: `boolean`):

Whether to fetch complete metadata for each video using the transcript endpoint (increases processing time and costs significantly).

## `includeComments` (type: `boolean`):

Whether to fetch comments for each video (only available when video details are included).

## `maxConcurrency` (type: `integer`):

Maximum number of concurrent channel requests. Higher values process faster but may hit rate limits. Recommended: 1-3.

## `videoLimit` (type: `integer`):

Maximum number of videos to process per channel when includeVideoDetails is enabled. Set to 0 for no limit.

## `includeWebhook` (type: `string`):

Optional webhook URL to receive results when channel profile & video list processing completes. Must be a publicly reachable URL that accepts POST requests.

## Actor input object example

```json
{
  "channelUrls": [
    "https://www.youtube.com/@google",
    "https://www.youtube.com/channel/UCK8sQmJBp8GCxrOtXWBpyEA"
  ],
  "includeVideoDetails": false,
  "includeComments": false,
  "maxConcurrency": 2,
  "videoLimit": 50
}
```

# 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/@google"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("transcriptdl/youtube-profile-channel-list-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/@google"] }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,transcriptdl/youtube-profile-channel-list-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/3A9tVNq3WUhU7hVs3/builds/58ph5bRfc76jT3KoN/openapi.json
