# YouTube Channel Details Scraper and Profile Enricher (`arjun_code/youtube-channel-details-scraper`) Actor

Unofficial YouTube channel profile scraper for handles, usernames, IDs, and URLs. Export subscriber, total-view, and video counts, join date, country, branding, public links, email signals, content tabs, and RSS—with one visible result per input. No API key.

- **URL**: https://apify.com/arjun\_code/youtube-channel-details-scraper.md
- **Developed by:** [Arjun AI](https://apify.com/arjun_code) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.25 / 1,000 youtube channel profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

### Enrich known YouTube channels with full public profiles

Turn a known list of YouTube channels into structured, analysis-ready profiles. Supply `@handles`, legacy usernames, channel IDs, channel URLs, or channel-tab URLs and receive one visible Dataset row per input: either a detailed public profile or a structured lookup status with corrective guidance.

This is a focused profile-enrichment Actor. It does not search by keyword and it does not expand channels into video or Shorts rows, so its input scope, output count, and downstream cost remain predictable. It is designed for creator-list enrichment, influencer qualification, CRM enrichment, competitor monitoring, audience research, and API or LLM workflows. No YouTube Data API key is required.

> This is an unofficial Actor and is not affiliated with, endorsed by, or sponsored by YouTube or Google. It collects publicly accessible metadata only.

### Ready-to-run examples

- [Get YouTube channel details](https://apify.com/arjun_code/youtube-channel-details-scraper/examples/get-youtube-channel-details)
- [Enrich a YouTube creator list](https://apify.com/arjun_code/youtube-channel-details-scraper/examples/enrich-youtube-creator-list)
- [Compare YouTube competitor channels](https://apify.com/arjun_code/youtube-channel-details-scraper/examples/compare-youtube-competitor-channels)

### Why this Actor is different

- **One input, one visible outcome:** every unique input produces either a profile row or a clear `channelLookupError` row.
- **Flexible direct lookup:** accepts handles, plain usernames, stable channel IDs, channel URLs, legacy user URLs, and channel-tab URLs.
- **Profile-first output:** combines identity, public statistics, history, branding, links, contact signals, badges, tabs, and RSS without adding unrelated video records.
- **Compact media fields:** returns one high-resolution `avatarUrl` and `bannerUrl` instead of large duplicate thumbnail arrays.
- **Honest contact coverage:** returns public emails only when they are directly exposed and separately reports when YouTube protects a business email behind sign-in.

### Choose the right Actor

| Goal | Recommended Actor |
|---|---|
| Enrich known channel handles, IDs, usernames, or URLs | This Actor |
| Discover channels, videos, or native Shorts by keyword | [YouTube Search Scraper](https://apify.com/arjun_code/youtube-search-scraper) |
| Export a known channel's videos, Shorts, and streams | [YouTube Channel Content Scraper](https://apify.com/arjun_code/youtube-channel-content-scraper) |
| Get metadata for known video or Shorts URLs or IDs | [YouTube Video and Shorts Details Scraper](https://apify.com/arjun_code/youtube-video-details-scraper) |
| Export public comments and replies from videos or Shorts | [YouTube Comments Scraper](https://apify.com/arjun_code/youtube-comments-scraper) |

### What it returns

- Stable channel identity: channel ID, name, handle, canonical URL, and ID-based URL
- Public description, channel keywords, profile type, and visibility metadata
- Public subscriber count, total channel views, and video count
- Standardized channel creation date plus YouTube's original displayed text
- Creator-selected country when the channel publishes one
- Verification, Official Artist Channel, memberships, and community availability
- High-resolution avatar and banner URLs without a large duplicate thumbnail array
- Public external links with platform labels and original link titles
- Email addresses exposed in the public channel page data
- Available channel tabs and direct URLs for Videos, Shorts, Live, Podcasts, Playlists, Posts, About, and RSS
- Family-safe, unlisted, and indexing metadata exposed by YouTube
- Visible `notFound`, `invalidInput`, `failed`, or `chargeLimitReached` Dataset rows when an input cannot produce a profile
- A compact `OUTPUT` summary with success or failure status for every input

### Pricing

This Actor uses pay per event, with Apify platform usage included in the listed prices.

| Event | Charged when | Price |
|---|---|---:|
| Actor start | Once when a run starts | **$0.00005 per run** |
| Channel profile | A resolved `recordType: "channel"` row is saved | **$0.00125 per profile** |
| Lookup status | A `channelLookupError` row is saved | **Free** |

Both `complete` and `partial` channel profiles are billable because they contain a resolved channel identity. `notFound`, `invalidInput`, `failed`, and `chargeLimitReached` rows are not charged as channel profiles.

Example totals before volume discounts:

| Resolved profiles | Total price |
|---:|---:|
| 1 | $0.00130 |
| 10 | $0.01255 |
| 50 | $0.06255 |

Each example includes one Actor-start event. The Actor also respects the maximum charge selected by the user. When the remaining budget cannot cover another profile, it stops saving billable profiles and writes a free `chargeLimitReached` status for affected inputs. The **Pricing** tab is the source of truth if prices change after this README is published.

### Input

The Actor has one input field: `channels`. Add one channel per line, with up to 50 unique values in a run.

Supported input formats:

| Input type | Example |
|---|---|
| Handle | `@NASA` |
| Plain username | `NASA` |
| Channel ID | `UCLA_DiR1FfKNvjuUpBHmylQ` |
| Handle URL | `https://www.youtube.com/@NASA` |
| Channel ID URL | `https://www.youtube.com/channel/UCLA_DiR1FfKNvjuUpBHmylQ` |
| Legacy user URL | `https://www.youtube.com/user/NASAtelevision` |
| Channel tab URL | `https://www.youtube.com/@NASA/videos` |

Example input:

```json
{
  "channels": [
    "@NASA",
    "UCRBrH2qS7yKGMNSmjnj8gcw",
    "https://www.youtube.com/@yttalkjun"
  ]
}
```

Plain usernames are resolved as a handle first, then through YouTube's legacy `/user/` and `/c/` channel paths.

### Output example

The selected fields below come from a real Actor `0.1.5` cloud run for `@FinancialTimes` on September 1, 2026. The full Dataset row contained additional fields; this example omits some of them for readability without inventing replacement values.

```json
{
  "recordType": "channel",
  "status": "complete",
  "inputValue": "@FinancialTimes",
  "inputType": "handle",
  "requestedUrl": "https://www.youtube.com/@FinancialTimes",
  "resolvedUrl": "https://www.youtube.com/@FinancialTimes/about?hl=en&gl=US",
  "channelId": "UCoUxsWakJucWg46KW5RsvPw",
  "channelName": "Financial Times",
  "channelHandle": "@FinancialTimes",
  "channelUrl": "https://www.youtube.com/@FinancialTimes",
  "channelIdUrl": "https://www.youtube.com/channel/UCoUxsWakJucWg46KW5RsvPw",
  "displayUrl": "www.youtube.com/@FinancialTimes",
  "subscriberCount": 1450000,
  "subscriberCountText": "1.45M subscribers",
  "subscriberCountHidden": false,
  "totalViewCount": 225062975,
  "totalViewCountText": "225,062,975 views",
  "videoCount": 11468,
  "videoCountText": "11,468 videos",
  "joinedDate": "2009-03-26",
  "joinedDateText": "Joined Mar 26, 2009",
  "channelCountry": "United Kingdom",
  "avatarUrl": "https://yt3.googleusercontent.com/ytc/AIdro_ndI2xm7Vhj_ZGTdd1hmWfv40vS_Pj1K9S31-NSBatSCLZb=s900-c-k-c0x00ffffff-no-rj",
  "isVerified": true,
  "isOfficialArtist": false,
  "profileType": "Person",
  "availability": "public",
  "hasCommunity": true,
  "socialLinks": [
    {
      "platform": "ft.com",
      "title": "Financial Times",
      "url": "https://www.ft.com"
    },
    {
      "platform": "X / Twitter",
      "title": "X",
      "url": "https://x.com/FinancialTimes"
    }
  ],
  "emails": [
    "syndication@ft.com"
  ],
  "businessEmailAvailable": false,
  "businessEmailRequiresSignIn": false,
  "availableTabs": [
    {
      "name": "Videos",
      "url": "https://www.youtube.com/@FinancialTimes/videos",
      "selected": false
    }
  ],
  "rssUrl": "https://www.youtube.com/feeds/videos.xml?channel_id=UCoUxsWakJucWg46KW5RsvPw",
  "scrapedAt": "2026-09-01T09:12:58.193596Z"
}
```

Counts and public page data change over time. Fields that a channel does not publish return `null`, `false`, or an empty array as appropriate.

### Output field reference

#### Input and status

| Field | Description |
|---|---|
| `recordType` | `channel` for a resolved profile or `channelLookupError` for an unresolved input. |
| `status` | `complete` or `partial` for profiles; `notFound`, `invalidInput`, `failed`, or `chargeLimitReached` for lookup-status rows. |
| `inputValue` | Original value supplied by the user. |
| `inputType` | Detected input type: `handle`, `username`, `channelId`, or `url`. |
| `requestedUrl` | Channel URL selected from the input. |
| `resolvedUrl` | Final URL returned after YouTube redirects. |
| `scrapedAt` | UTC timestamp when the record was created. |

#### Identity and profile

| Field | Description |
|---|---|
| `channelId` | Stable YouTube channel ID. |
| `channelName` | Current public channel name. |
| `channelHandle` | Current `@handle` when available. |
| `channelUrl` | Preferred public channel URL, normally the handle URL. |
| `channelIdUrl` | Stable `/channel/CHANNEL_ID` URL. |
| `displayUrl` | URL text displayed by YouTube. |
| `description` | Full public channel description. |
| `keywords` | Channel keywords exposed in public page metadata. |
| `profileType` | Structured entity type exposed by YouTube. It can be `Person` even for an organizational channel. |

#### Audience and history

| Field | Description |
|---|---|
| `subscriberCount` | Parsed public subscriber count. Public counts may be rounded by YouTube. |
| `subscriberCountText` | Subscriber count exactly as displayed. |
| `subscriberCountHidden` | Whether the channel hides its public subscriber count. |
| `totalViewCount` | Parsed lifetime public channel view count. |
| `totalViewCountText` | Total views exactly as displayed. |
| `videoCount` | Parsed public video count displayed by YouTube. |
| `videoCountText` | Video count exactly as displayed. |
| `joinedDate` | Standard `YYYY-MM-DD` channel join date. |
| `joinedDateText` | Original YouTube join-date text. |
| `channelCountry` | Creator-selected public country; `null` when not published. |

#### Branding and channel features

| Field | Description |
|---|---|
| `avatarUrl` | Best available public channel avatar URL. |
| `bannerUrl` | Best available public channel banner URL. |
| `isVerified` | Whether YouTube displays a verified badge. |
| `isOfficialArtist` | Whether the header identifies an Official Artist Channel. |
| `hasMemberships` | Whether a public Join/membership action is displayed. |
| `hasCommunity` | Whether Posts or Community content is exposed. |
| `isFamilySafe` | Family-safe metadata exposed by YouTube. |
| `isUnlisted` | Whether public page metadata marks the channel as unlisted. |
| `isNoIndex` | Whether public page metadata asks search engines not to index the channel. |
| `availability` | Public availability classification. |

#### Contact, navigation, and availability

| Field | Description |
|---|---|
| `socialLinks` | External channel links with platform, title, and destination URL. |
| `emails` | Email addresses exposed in the public channel page source or description. |
| `businessEmailAvailable` | Whether YouTube displays a business-email action. |
| `businessEmailRequiresSignIn` | Whether YouTube requires an authenticated session to reveal that business email. |
| `availableTabs` | Channel tabs currently exposed by YouTube, with URLs. |
| `contentUrls` | Direct navigation map for available content tabs, About, and RSS. |
| `rssUrl` | YouTube uploads RSS feed for the channel. |

### Email limitations

The Actor only returns email addresses present in publicly delivered channel data. YouTube may require sign-in and CAPTCHA completion before revealing a business email. The Actor does not bypass those controls. In that case, `businessEmailAvailable` and `businessEmailRequiresSignIn` can be `true` while `emails` remains empty.

### Unresolved channels and run summary

The default Dataset contains one row for every unique input. Resolved inputs use `recordType: "channel"`. If a channel does not exist, is misspelled, is invalid, cannot be extracted, or cannot be saved within the user's maximum charge, the Dataset contains a compact `recordType: "channelLookupError"` row instead of silently returning no data:

```json
{
  "recordType": "channelLookupError",
  "status": "notFound",
  "inputValue": "@channel_that_does_not_exist",
  "inputType": "handle",
  "errorCode": "CHANNEL_NOT_FOUND",
  "errorMessage": "No public YouTube channel matched this input.",
  "suggestion": "Check the spelling, @handle, channel ID, or channel URL.",
  "scrapedAt": "2026-09-01T04:38:17Z"
}
```

The default Key-Value Store record named `OUTPUT` also reports totals and the result of every input:

```json
{
  "totalInputs": 1,
  "completeChannels": 0,
  "partialChannels": 0,
  "notFoundInputs": 1,
  "invalidInputs": 0,
  "failedInputs": 0,
  "chargeLimitedInputs": 0,
  "totalResults": 0,
  "statusDatasetItems": 1,
  "totalDatasetItems": 1,
  "chargeLimitReached": false,
  "resultsByInput": [
    {
      "inputValue": "@channel_that_does_not_exist",
      "status": "notFound",
      "errorCode": "CHANNEL_NOT_FOUND",
      "error": "No public YouTube channel matched this input. Check the spelling, @handle, channel ID, or channel URL."
    }
  ]
}
```

### Run through the Apify API

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/arjun_code~youtube-channel-details-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channels": [
      "@NASA",
      "UCLA_DiR1FfKNvjuUpBHmylQ"
    ]
  }'
```

### Troubleshooting

#### A valid channel returned a lookup error

Check the input spelling and open the supplied channel URL in a signed-out browser. If it is public, retry once because YouTube can temporarily return an incomplete or blocked response. Include the run ID in a support request so the exact attempt can be inspected.

#### `emails` is empty although the channel shows a business-email button

YouTube can expose only the presence of the button while requiring sign-in and CAPTCHA to reveal the address. In that case, `businessEmailAvailable` or `businessEmailRequiresSignIn` can be `true` while `emails` remains empty. Addresses written directly in public descriptions or page data can still be returned.

#### A count or profile field is `null`

The channel did not publish the value, hid it, or YouTube omitted it from the public response. The Actor keeps missing values empty instead of estimating them. Public subscriber values can be rounded by YouTube; use `subscriberCountText` when the displayed label matters.

### FAQ

#### Can this Actor discover channels by keyword?

No. This Actor enriches channels you already know by handle, username, ID, or URL. Use [YouTube Search Scraper](https://apify.com/arjun_code/youtube-search-scraper) for keyword discovery.

#### Does it return videos or Shorts?

No. It returns one channel profile per input and reports the channel's public video count. Use [YouTube Channel Content Scraper](https://apify.com/arjun_code/youtube-channel-content-scraper) to export videos, Shorts, or streams from a known channel. Use [YouTube Search Scraper](https://apify.com/arjun_code/youtube-search-scraper) for keyword discovery.

#### Are email addresses guaranteed?

No. The Actor returns only email addresses exposed in publicly delivered channel data. A protected business-email action can be detected even when the address itself requires sign-in and CAPTCHA completion.

#### Why can a field be `null` or an array be empty?

YouTube channels do not all publish the same metadata. Country, handle, banner, subscriber count, links, emails, and some channel tabs can be hidden or absent. The Actor preserves that distinction instead of inventing values.

#### What happens when a channel does not exist?

The Dataset still receives a visible, non-billable `channelLookupError` row with `status: "notFound"`, an error code, a message, and a suggested correction.

#### Which results are charged?

Only resolved `recordType: "channel"` rows are charged as channel profiles. Lookup-status rows are free. The small Actor-start event is charged once per run.

#### How many channels can one run process?

Up to 50 unique channel inputs. Every accepted input produces one visible Dataset outcome.

#### Is a YouTube Data API key required?

No.

### Support

If an input resolves incorrectly or a public field is unexpectedly missing, open an issue from the Actor's Apify page and include:

- the Actor run URL or run ID;
- the exact channel input;
- the expected value;
- the Dataset row or field that was returned.

Do not include your Apify API token, account credentials, or other secrets. YouTube changes public page data over time, so a reproducible run link is the fastest way to investigate.

### Responsible use

Use the Actor only for lawful processing of publicly accessible information. Respect YouTube's terms, applicable privacy and data-protection requirements, and the rights of channel owners. Do not use contact data for spam, harassment, or deceptive outreach.

This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by YouTube or Google.

# Actor input Schema

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

Add one known channel identifier per line. Examples: @NASA, NASA, UCLA\_DiR1FfKNvjuUpBHmylQ, https://www.youtube.com/@NASA, or https://www.youtube.com/channel/UCLA\_DiR1FfKNvjuUpBHmylQ. This field performs direct channel lookup, not keyword search.

## Actor input object example

```json
{
  "channels": [
    "@NASA"
  ]
}
```

# Actor output Schema

## `channels` (type: `string`):

No description

## `summary` (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 = {
    "channels": [
        "@NASA"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arjun_code/youtube-channel-details-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": ["@NASA"] }

# Run the Actor and wait for it to finish
run = client.actor("arjun_code/youtube-channel-details-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": [
    "@NASA"
  ]
}' |
apify call arjun_code/youtube-channel-details-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arjun_code/youtube-channel-details-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/P5PJeaR58HqCSLtdL/builds/Meh49FLFeMHP8aXyc/openapi.json
