# YouTube Channel Email & Influencer Contacts Finder (`datagleaner/youtube-channel-contacts`) Actor

YouTube channel email finder for influencer contacts: $0.015 per channel with a public email, free when none is found. Give channel URLs or a keyword; get each youtuber's email, website, Instagram, TikTok and X. No login, no CAPTCHA.

- **URL**: https://apify.com/datagleaner/youtube-channel-contacts.md
- **Developed by:** [Data Gleaner](https://apify.com/datagleaner) (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

$15.00 / 1,000 channel with 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

## YouTube Channel Email Scraper and Influencer Contact Finder

Get the public email of any YouTube channel, plus website, Instagram, TikTok and X, for influencer outreach. $0.015 per channel with an email; channels without one are free.

Give it channels (URLs, @handles, IDs, or a video or Shorts link) or a niche keyword such as `fitness coach`. Each channel comes back as one row with its **public emails, phones, website and social profiles**, the page each email was found on, and subscriber, video and country stats for filtering. No login, no YouTube API key, no CAPTCHA. Unlike hidden-email scrapers, it returns only what the creator published openly, so a miss costs nothing. The fields are the same on every row, so AI agents and lead-generation pipelines can use it as well as people.

### What it finds

Every contact the channel shows **publicly**: emails written in the description, the links listed in the About section (Instagram, TikTok, X, Facebook, LinkedIn, Twitch, Discord, a website, a Linktree and so on), and the emails, phones and socials on the creator's own website or link-in-bio page. It uses plain HTTP: no browser.

It does **not** reveal the hidden "View email address" button. That button sits behind a CAPTCHA and a sign-in, and this Actor never touches it. For each channel it reports whether the button exists (`hasBusinessEmailButton: true` marks a channel with a hidden business email that this Actor does not reveal), so you can see which creators have an address you would have to request by hand.

Phones are only returned when the channel publishes one: valid E.164 numbers from the description, About link titles and followed pages. `phones` is often empty.

### Use cases

- Influencer marketing and creator outreach lists, built by niche keyword.
- Agencies enriching a list of channels with the contact route each creator already published.
- Sponsorship, affiliate and PR prospecting: filter by subscriber range and country, keep only channels with an email.
- An AI agent or enrichment pipeline that needs "the youtuber's contact email" for a list of channels, paying only for hits.
- Finding the creator's other platforms (Instagram, TikTok, X) from their YouTube channel.

### How it works

1. A channel input is turned into the channel's About page. A keyword is searched on YouTube (channels only) and paged until `maxChannelsPerKeyword`.
2. The About data (description, links, subscribers, videos, views, joined date, country) is read from the page's own JSON.
3. Emails and phones are read from the description. Links are classified into socials, link-in-bio pages and websites.
4. With `followLinks` on (default), up to **3 pages per channel** are visited: link-in-bio pages first, then the creator's website, then its contact page if no email was found. Emails on those pages are kept only when they plausibly belong to the creator (the site's own domain, a free mailbox, or a name the channel itself uses); addresses of site builders, store platforms, link-in-bio services and payment processors are dropped.

### Input

| Field | Meaning |
|---|---|
| `channels` | Channel URLs, `@handles` or `UC...` IDs. A video or Shorts link also works and stands for the channel that uploaded it. |
| `searchKeywords` | Find channels by keyword, e.g. `fitness coach`. |
| `maxChannelsPerKeyword` | Channels taken per keyword (default 20, max 500). |
| `minSubscribers`, `maxSubscribers` | Subscriber range. YouTube rounds public counts to 3 significant digits. |
| `country` | ISO code or name from the About page. Channels with no country listed are skipped when set. |
| `joinedAfter`, `joinedBefore` | Keep channels created on or after / before this date (`YYYY-MM-DD`), e.g. to find new creators. Channels with no join date are kept. |
| `searchCountry` | Two-letter country code that localizes keyword search (default `US`). Does not filter channels by their own country; use `country`. |
| `searchLanguage` | Interface language for keyword search (default `en`; e.g. `de`, `pt-BR`). |
| `followLinks` | Visit up to 3 website / link-in-bio pages per channel (default true). |
| `onlyWithEmail` | Output only channels with a public email (default false). Channels without one are free either way. |
| `maxConcurrency`, `delaySecs`, `requestTimeoutSecs`, `respectRobotsTxt`, `proxyConfiguration` | Pacing and network options. No proxy by default. |

Leave everything empty to run five sample channels (about 10 seconds).

```json
{
  "searchKeywords": ["fitness coach"],
  "maxChannelsPerKeyword": 30,
  "minSubscribers": 1000,
  "maxSubscribers": 500000,
  "onlyWithEmail": true
}
```

### Output

One row per channel. Fields that were not found are empty, never invented.

```json
{
  "channelId": "UCBJycsmduvYEL83R_U4JriQ",
  "handle": "@mkbhd",
  "title": "Marques Brownlee",
  "url": "https://www.youtube.com/@mkbhd",
  "subscribers": 21400000,
  "videos": 1856,
  "views": 5752184125,
  "joinedAt": "2008-03-21",
  "country": "United States",
  "countryCode": "US",
  "description": "MKBHD: Quality Tech Videos ...",
  "thumbnailUrl": "https://yt3.googleusercontent.com/...",
  "isVerified": true,
  "email": "business@mkbhd.com",
  "emailType": "business",
  "hasEmail": true,
  "emails": [{"email": "business@mkbhd.com", "type": "business", "source": "description", "foundOn": "https://www.youtube.com/@mkbhd"}],
  "phones": [],
  "links": [{"title": "Instagram", "url": "http://instagram.com/MKBHD", "source": "about"}],
  "socials": {"x": "https://x.com/MKBHD", "instagram": "https://www.instagram.com/MKBHD", "discord": "https://discord.gg/MKBHD"},
  "website": null,
  "instagramUrl": "https://www.instagram.com/MKBHD",
  "tiktokUrl": null,
  "xUrl": "https://x.com/MKBHD",
  "facebookUrl": null,
  "linkedinUrl": null,
  "hasBusinessEmailButton": true,
  "pagesFollowed": 0,
  "status": "ok",
  "input": "@mkbhd",
  "scrapedAt": "2026-10-08T15:25:52+00:00"
}
```

`email` is the best address (business and collaboration mailboxes first, shop support last) and `emailType` is `business`, `general` or `support`; `emails` lists all of them, best first. `instagramUrl`, `tiktokUrl`, `xUrl`, `facebookUrl` and `linkedinUrl` repeat the matching `socials` entries as flat columns. The dataset has two views: "Channel contacts" and "All emails". `emails[].source` is `description`, `about-link`, `link-in-bio` or `website`; `foundOn` is the exact page. A channel that cannot be read (not found, blocked) gets a row with `status: "error"` and an `error` message, and is not charged.

### Pricing

Pay per answer, one event:

- **`channel-with-email`: $0.015** for each channel where at least one public email was found.
- A channel with **no email is free**. It is still returned, with its links, socials and stats, so you can see why.
- A channel that cannot be read (`status: "error"`) is free.

**Worked example.** You search a niche and get 1,000 channels, 30% of which show a public email: 300 x $0.015 = **$4.50**. The 700 channels without an email cost nothing. Turn on `onlyWithEmail` to leave them out of the dataset; the price is the same.

**Compared with $0.12 per email.** Hidden-email YouTube scrapers in the Store charge about $0.12 per email ($120 per 1,000). Here a found email costs $0.015, an eighth of that, and a miss costs nothing. The difference is what you get: those tools try to retrieve the address behind the CAPTCHA button; this Actor returns only what the creator published openly, so fewer channels have an email, but every address comes with the page it was found on.

Set a maximum total charge on the run and the Actor stops cleanly when it is reached.

### What to expect

Measured on test runs: about 45% of a mixed sample of 20 channels had a public email, and about 20 to 30% of a 30-channel "fitness coach" search. Small channels rarely publish one. Around 60% of channels have the hidden business-email button, so many creators can only be reached through it; those rows still carry their links and socials.

### Limits

- Subscriber counts are YouTube's rounded public numbers (for example 21.4M, 33K).
- Only the first 3 pages per channel are followed, and only the channel's own links. Social platforms are listed, never scraped.
- Link-in-bio pages that render entirely with JavaScript may show fewer links.
- Search returns what YouTube returns for the keyword; very deep paging may repeat or end early.
- Heavy runs from one IP can be rate limited by YouTube; lower `maxConcurrency` or add a proxy.

### Use with Python

```python
## pip install apify-client
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("datagleaner/youtube-channel-contacts").call(run_input={
    "searchKeywords": ["fitness coach"],
    "maxChannelsPerKeyword": 5,  # at most 5 x $0.015 = $0.075
})
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item.get("title"), item.get("subscribers"), [e["email"] for e in item.get("emails", [])])
```

### Use with JavaScript / Node.js

```js
// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datagleaner/youtube-channel-contacts').call({
    channels: ['@mkbhd', '@aliabdaal'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
    console.log(item.title, (item.emails || []).map((e) => e.email), item.socials);
}
```

### Use it from n8n, Make, Zapier or an AI agent

Actor ID: `datagleaner/youtube-channel-contacts`

Minimal input:

```
{
  "searchKeywords": ["fitness coach"],
  "maxChannelsPerKeyword": 5
}
```

Each tool below runs this Actor with your own Apify API token.

- **n8n:** add the **Apify** node (`@apify/n8n-nodes-apify`). On n8n Cloud you install it from the community node registry. Choose **Run an Actor and get dataset**, set Actor to `datagleaner/youtube-channel-contacts` and paste the input above.
- **Make:** use the Apify app's **Run an Actor** module, then **Get Dataset Items** to read the results. **Watch Actor Runs** can trigger a scenario when a run finishes.
- **Zapier:** use the Apify action **Run Actor**, then the search **Fetch dataset items**. The trigger **Finished Actor run** starts a Zap when a run ends.
- **AI agents (MCP):** connect to `https://mcp.apify.com?tools=datagleaner/youtube-channel-contacts`. In Claude Code:

  ```
    claude mcp add --transport http apify "https://mcp.apify.com?tools=datagleaner/youtube-channel-contacts"
  ```

  Then run `/mcp` to sign in to Apify in your browser. Then ask in plain words, for example: "Find 20 YouTube channels about home workouts with 10K to 200K subscribers in the US, and give me each creator's public email, Instagram and website as a table."
- **LangChain (Python):**

```python
## pip install langchain-apify, then set APIFY_TOKEN in your environment
import json
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("datagleaner/youtube-channel-contacts")
result = tool.invoke({"run_input": json.loads('{"searchKeywords": ["fitness coach"], "maxChannelsPerKeyword": 5}')})
```

### FAQ

**How do I find a YouTube channel's email address?** Give the channel URL or @handle to this Actor. It reads the email written in the channel description and About links, then checks the creator's website and link-in-bio page, and returns each address with the page it came from.

**Does it get the "business email" behind the "View email address" button?** No. That button needs a sign-in and a CAPTCHA, and this Actor never touches it. `hasBusinessEmailButton` tells you which channels have one.

**Can I find YouTube influencers by niche and get their contacts?** Yes. Put a keyword in `searchKeywords`, set `minSubscribers`, `maxSubscribers` and `country`, and turn on `onlyWithEmail` to keep only creators with a public email.

**Do I need a YouTube API key or login?** No.

**Which channel formats does it accept?** `https://www.youtube.com/@name`, `@name`, `youtube.com/channel/UC...`, `/c/name`, `/user/name`, a bare channel ID, or a video, Shorts, live or embed link (resolved to the channel that uploaded it).

### Responsible use

This Actor reads public pages only. Email addresses and phone numbers can be personal data. You are responsible for lawful use, including consent and opt-out rules for outreach (GDPR, CAN-SPAM and local law) and for respecting the terms of the platforms you use the data on.

# Actor input Schema

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

Channel URLs, @handles or channel IDs (UC...), one per line. A video or Shorts link also works: it stands for the channel that uploaded it. Leave this and the keywords empty to run the sample channels.

## `searchKeywords` (type: `array`):

Find channels through YouTube search, for example `fitness coach` or `vegan recipes`. Each keyword is searched separately.

## `maxChannelsPerKeyword` (type: `integer`):

How many channels to take from each keyword search.

## `minSubscribers` (type: `integer`):

Skip channels with fewer subscribers. YouTube rounds public counts to 3 significant digits.

## `maxSubscribers` (type: `integer`):

Skip channels with more subscribers. Useful to target micro-influencers.

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

Keep only channels whose About page lists this country, as an ISO code (`US`, `GB`) or name (`United States`). Channels that list no country are skipped when this is set.

## `joinedAfter` (type: `string`):

Keep only channels created on or after this date (YYYY-MM-DD). Finds new creators. Channels with no join date on the About page are kept.

## `joinedBefore` (type: `string`):

Keep only channels created on or before this date (YYYY-MM-DD).

## `searchCountry` (type: `string`):

Two-letter country code (`US`, `IN`, `DE`) YouTube search is localized to, so a keyword run finds the channels shown to that market. Does not filter channels by their own country: use Country for that.

## `searchLanguage` (type: `string`):

Interface language code for keyword search (`en`, `hi`, `de`, `pt-BR`).

## `checkEmailDomains` (type: `boolean`):

Look up the mail servers of each email's domain and set hasMx on every email. Nothing is dropped and the price does not change; hasMx false means the domain cannot receive mail, null means the lookup failed.

## `followLinks` (type: `boolean`):

Visit up to 3 of the channel's own links (Linktree-style pages and the creator's website) and collect the emails, phones and socials shown there.

## `onlyWithEmail` (type: `boolean`):

Output only channels where at least one public email was found. Channels without an email are free either way.

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

How many channels are processed at the same time. Keep it low; YouTube slows down heavy traffic from one IP.

## `respectRobotsTxt` (type: `boolean`):

Skip website pages that the site's robots.txt disallows.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each page before retrying.

## `proxyConfiguration` (type: `object`):

Optional. Defaults to no proxy. Use a proxy if YouTube starts answering with errors on large runs.

## `delaySecs` (type: `integer`):

Each channel starts after a random pause of up to this many seconds. Raise it on very large runs to stay polite.

## Actor input object example

```json
{
  "channels": [
    "@mkbhd",
    "@aliabdaal",
    "@MadFit",
    "@AtHomeWithAshley",
    "@sunnyvadje2510"
  ],
  "maxChannelsPerKeyword": 20,
  "searchCountry": "US",
  "searchLanguage": "en",
  "checkEmailDomains": true,
  "followLinks": true,
  "onlyWithEmail": false,
  "maxConcurrency": 5,
  "respectRobotsTxt": true,
  "requestTimeoutSecs": 25,
  "delaySecs": 1
}
```

# Actor output Schema

## `results` (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": [
        "@mkbhd",
        "@aliabdaal",
        "@MadFit",
        "@AtHomeWithAshley",
        "@sunnyvadje2510"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagleaner/youtube-channel-contacts").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",
        "@aliabdaal",
        "@MadFit",
        "@AtHomeWithAshley",
        "@sunnyvadje2510",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("datagleaner/youtube-channel-contacts").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",
    "@aliabdaal",
    "@MadFit",
    "@AtHomeWithAshley",
    "@sunnyvadje2510"
  ]
}' |
apify call datagleaner/youtube-channel-contacts --silent --output-dataset

```

## MCP server setup

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

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/0pygk9iSXsojnWQOx/builds/TiwUau9T32ZvWhQaW/openapi.json
