# YouTube Creator Email Finder — Contacts & Channel Stats (`devjoi/youtube-creator-emails`) Actor

Find public business emails of YouTube creators worldwide — by channel or keyword. Extracts contact emails from descriptions and linked websites, checks every address (format + mail records), and returns channel stats plus social links. Pay only for emails found: $5 per 1,000.

- **URL**: https://apify.com/devjoi/youtube-creator-emails.md
- **Developed by:** [Joinner Medina](https://apify.com/devjoi) (community)
- **Categories:** Lead generation, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 emails

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?

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

The **YouTube Creator Email Finder** finds **publicly available contact emails** for YouTube channels — in **any country or
language** — plus subscriber counts, view counts, join date, country and external
links. Server-side, **no login, no browser, no email sending**. **You pay only for
emails found.**

### What it does

| Input | Result |
|---|---|
| Channel handles / URLs / IDs (`@mkbhd`, `https://youtube.com/@x`, `UC...`) | One dataset row per channel with stats + public emails |
| Search queries (`"tech review"`, `"beauty tips"`) | The top channel results of the query (up to 30), then processed like above |

Per channel the actor:

1. Reads the public `.../about` page (embedded `ytInitialData` payload — the same data the page renders from).
2. Extracts description, subscriber count, views, join date, country and external links (redirects resolved).
3. Extracts **public emails** from the description and, optionally, from the channel's **own linked website** (homepage + up to 2 contact/about pages; social profiles are never crawled). Common obfuscations like `name [at] domain [dot] com` are converted.
4. Validates every address through the full set: format checks, domain mail-server lookup (DNS "MX" records) and noise filtering — dead or malformed addresses are dropped (`valid_syntax`, `has_mx`, `mx_hosts` in the output). No email is ever sent.
5. Flags channels whose business email exists but requires sign-in (`email_hidden_behind_login: true`) — the address itself is not returned, because it is not public.

### When should you use this Actor?

- *"I need contact emails of YouTube creators for outreach or sponsorships."* — give it channels or a niche search and get validated contacts back.
- *"I have a list of channel handles or URLs and need their emails and stats."* — one row per channel: emails, subscribers, views, country and links.
- *"I want to discover creators in a niche and reach out."* — run search queries like `"tech review"` and get the top channels with contacts.
- *"I need to watch for new creator contacts over time."* — enable **Only new emails** and schedule the run; each run returns only emails not seen before.

### Why this Actor

- **Pay only for emails found** — **$5 per 1,000 emails**; channels without a discoverable public email are free to process.
- **Validated, not guessed** — every address passes format checks, mail-server ("MX") record lookup and noise filtering before it reaches the output.
- **Honest about limits** — business emails hidden behind sign-in are flagged (`email_hidden_behind_login`), never invented; no captcha bypass, no login walls, no SMTP probing. Observed coverage is typically 20–35% of channels, depending on the niche.
- **Worldwide** — channels from any country and language, with subscriber/view stats and typed external links.

### Use cases

- **Influencer outreach & sponsorships** — build creator contact lists for brand deals.
- **Niche discovery** — run keyword searches ("fitness", "SaaS reviews") and get the top channels in that niche, with contacts.
- **Ongoing monitoring** — schedule weekly runs with `onlyNewEmails` to receive only the contact details that are new.
- **CRM enrichment** — feed handles you already have; get stats + contacts as clean JSON.

### Input example

```json
{
  "channels": ["@mkbhd", "https://www.youtube.com/@MrBeast"],
  "searchQueries": ["tech review"],
  "maxChannels": 50,
  "enrichFromLinks": true,
  "validateMx": true,
  "onlyNewEmails": false
}
```

All fields are optional — provide `channels`, `searchQueries`, or both. The full field reference is in the **Input** tab.

### Output

One row per channel: `handle`, `url`, `title`, `description`, `subscriber_count`,
`view_count`, `joined_date`, `country`, `links` (typed: website / social / other),
`emails` (with `source` + validation: `valid_syntax`, `has_mx`, `mx_hosts`), `email_hidden_behind_login`,
`scraped_at`. See the Output tab for a real example.

### Pricing

**Pay per event — you are charged only for emails found** (`email-found` event):
**$5.00 per 1,000 email addresses** returned (plus a nominal run start fee).
Channels without a discoverable public email are free to process, and full email
validation (format + mail records) is included at no extra charge.

### Honest scope

- Only **publicly visible** emails are returned. Channels without a public contact email produce a row with an empty `emails` array — never a guessed address.
- Observed public-email coverage on samples: roughly **20–35% of channels**, depending on niche.
- No captcha bypass, no login walls, no SMTP probing, no personal-data guessing.

### FAQ

- **Do I pay for channels with no email?** No — only found emails are charged.
- **Why is an email I see on YouTube not in the output?** Some business emails sit behind YouTube's sign-in wall; those channels are flagged (`email_hidden_behind_login`) instead of pretending to fetch the address.
- **Which countries and languages are covered?** All — channels are processed worldwide, in any language; the channel's public country (when set) is included in the output.
- **Does it send emails or test mailboxes?** Neither — validation is address format + the domain's public mail-server (MX) records. Nothing is ever sent or probed.
- **How do I monitor for new emails?** Enable `onlyNewEmails` and schedule the actor; each run returns only emails not seen in previous runs.

### Run via API or MCP

```bash
curl -X POST "https://api.apify.com/v2/acts/devjoi~youtube-creator-emails/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"channels": ["@mkbhd"], "maxChannels": 20}'
```

The Actor is fully described by its input/output schemas, so LLM agents can discover and call it through the Apify MCP server.

### Development

```bash
npm install
npm test                 # 32 tests: unit (parsing, emails), e2e pipeline (stubbed HTTP + real-shaped fixtures), dataset schema (incl. negative cases)
npm run local            # live run against YouTube with a demo input (writes local-output.json)
RUN_LIVE=1 npm run test:live   # live integration test (real network)
node scripts/validate-dataset-schema.mjs   # validate local-output.json against .actor/dataset_schema.json
```

Layout: `src/main.js` (Apify wiring) · `src/core/pipeline.js` (all business logic,
dependency-injected) · `src/lib/` (http, html-json, youtube, emails, pool) ·
`.actor/` (schemas) · `tests/` (fixtures modeled on real page shapes).

# Changelog

This Actor's version history is a separate document: https://apify.com/devjoi/youtube-creator-emails/changelog.md

# Actor input Schema

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

Channels to analyze. Each item can be a handle ("@mkbhd"), a bare handle ("mkbhd"), a full URL ("https://www.youtube.com/@mkbhd") or a channel ID ("UC..."). Maximum 5,000 channels per run.

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

YouTube search terms. The top channel results of each query are collected automatically (up to 30 channels per query). Useful for discovering creators in a niche.

## `maxChannels` (type: `integer`):

Safety cap on how many channels are processed per run (after resolving search queries and de-duplicating).

## `enrichFromLinks` (type: `boolean`):

When a channel links to its own website, visit it (homepage and up to 2 contact/about pages) to look for contact emails. Social profiles (Instagram, TikTok, X...) are never crawled.

## `validateMx` (type: `boolean`):

Check that the domain of each found email has public mail records ('MX' in DNS) — a deliverability signal. Result is reported per email as `has_mx`. No email is ever sent.

## `onlyNewEmails` (type: `boolean`):

Output only emails not seen in previous runs of this actor (per channel). Ideal for scheduled monitoring of new creators' contact details.

## `concurrency` (type: `integer`):

How many channels are processed in parallel (1-10).

## Actor input object example

```json
{
  "channels": [
    "@mkbhd",
    "https://www.youtube.com/@MrBeast",
    "UCBJycsmduvYEL83R_U4JriQ"
  ],
  "searchQueries": [
    "tech review",
    "beauty tips"
  ],
  "maxChannels": 100,
  "enrichFromLinks": true,
  "validateMx": true,
  "onlyNewEmails": false,
  "concurrency": 4
}
```

# Actor output Schema

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

All channels with their emails and stats as dataset items (JSON, CSV, Excel or XML via the API).

## `summary` (type: `string`):

Run statistics: channels processed, emails found/validated, failures.

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

// Run the Actor and wait for it to finish
const run = await client.actor("devjoi/youtube-creator-emails").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": [
        "@mkbhd",
        "@jasanahis",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("devjoi/youtube-creator-emails").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": [
    "@mkbhd",
    "@jasanahis"
  ]
}' |
apify call devjoi/youtube-creator-emails --silent --output-dataset

```

## MCP server setup

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

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/lz5znjzG5yUh5yEEN/builds/ZbSKzOWejvMMwdZ2a/openapi.json
