# YouTube Channel Email & Metadata Scraper (`lance_api/youtube-channel-email-metadata-scraper`) Actor

Extract public email addresses and rich metadata from YouTube channels, including channel details, subscriber counts, descriptions, links, and other available contact information. Built for lead generation, creator outreach, CRM enrichment, and API automation.

- **URL**: https://apify.com/lance_api/youtube-channel-email-metadata-scraper.md
- **Developed by:** [LanceAPI](https://apify.com/lance_api) (community)
- **Categories:** AI, Social media
- **Stats:** 8 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 results

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 Email Scraper API

> **Search reliability upgrade:** Keyword discovery uses a managed provider failover chain. The primary provider is used first, and a fallback provider is attempted only when the current provider fails—not when it simply returns fewer channels than the requested maximum. At most three providers are attempted per search query. Direct URL/channel inputs remain independent from keyword-search infrastructure.

**Find YouTube creators, extract public business emails, and collect channel data in one API-ready workflow.**

Submit YouTube channel URLs, handles, channel IDs, or video URLs—or search by niche and keyword. Get structured records containing **public emails, phone numbers, websites, social profiles, subscriber counts, views, channel metadata, and processing status**.

Built for **creator outreach, influencer discovery, sponsorship research, lead generation, CRM enrichment, market analysis, and automated data pipelines**. Start with a single channel or discover hundreds of creators without building your own search, resolution, deduplication, and data-cleaning workflow.

- **Flexible input:** known channels, handles, IDs, videos, or keywords
- **Contact-ready output:** public emails, phones, websites, and social profiles
- **Developer-friendly:** stable JSON, documented fields, and API examples
- **Clear pricing:** keyword-search fees plus an email-found fee only when a public email is returned
- **Public data only:** no private access, login-wall bypass, or CAPTCHA solving

### ⭐ Key features

#### Find creators in two ways

Process creators you already know or use keyword search to discover channels by topic, niche, or market. Both modes can run together.

#### Extract public contact information

Return public email strings, phone numbers, websites, and social profiles exposed through supported YouTube channel data.

#### Enrich every result with channel intelligence

Combine contact fields with channel name, handle, ID, subscribers, total views, video count, country, join date, avatar, banner, and verification status.

#### Accept practical YouTube input formats

Use channel URLs, `@handles`, channel IDs, custom/user URLs, standard video URLs, Shorts URLs, or `youtu.be` links. Video inputs are resolved to their uploader channels.

#### Build automation-ready datasets

Each returned channel uses a predictable schema with source context, normalized fields, success/failure status, timestamps, and error details.

#### Understand hidden business-email signals

`hasHiddenEmail` indicates that YouTube appears to show a business-email option behind its verification flow. It does **not** mean the hidden address was extracted.

### 🚀 Quick input example

```json
{
  "urls": [
    "https://www.youtube.com/@Google"
  ],
  "searchQueries": [
    "AI automation creators"
  ],
  "maxResultsPerQuery": 20,
  "country": "US",
  "language": "en-US"
}
```

### Short output example

```json
{
  "status": "success",
  "channelName": "Example Creator",
  "channelHandle": "@examplecreator",
  "channelId": "UCwx4iod3ECHlNOk9iEJB9xA",
  "channelUrl": "https://www.youtube.com/channel/UCwx4iod3ECHlNOk9iEJB9xA",
  "youtubeEmail": "business@example.com",
  "hasEmail": true,
  "hasHiddenEmail": false,
  "subscriberCount": 125000,
  "country": "United States",
  "websiteUrl": "https://example.com/",
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

A complete output example with contact arrays, social links, metadata, and run fields appears in [Complete output example](#complete-output-example).

### Input

Provide at least one non-empty value in `urls` or `searchQueries`.

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `urls` | string\[] | No\* | `[]` | Up to 200 channel URLs, handles, channel IDs, custom/user URLs, video URLs, Shorts URLs, or `youtu.be` links. |
| `searchQueries` | string\[] | No\* | `[]` | Up to 20 keywords used to discover YouTube channels. |
| `maxResultsPerQuery` | integer | No | `20` | Maximum number of channels to return per keyword. The actual number may be lower. Minimum 1, maximum 200. |
| `country` | string | No | empty | Country localization for keyword search relevance. Ignored for direct inputs. |
| `language` | string | No | empty | Language localization for keyword search relevance. Ignored for direct inputs. |
| `joinedDateFrom` | string | No | empty | Keep channels created on or after this date. Format: `YYYY-MM-DD`. |
| `joinedDateTo` | string | No | empty | Keep channels created on or before this date. Format: `YYYY-MM-DD`. |

\* At least one of `urls` or `searchQueries` is required.

#### Input behavior

- Each non-empty direct input is processed independently, including repeated inputs.
- Video and Shorts URLs resolve to the uploader channel.
- Search results are deduplicated by stable channel ID.
- Direct and search modes can be combined in one run.
- `maxResultsPerQuery` is an upper bound, not a minimum delivery target. If the active search provider succeeds with fewer channels, the Actor accepts those results and does not call another provider just to fill the remaining quantity.
- `country` and `language` localize search relevance; they do not hard-filter returned channel metadata.
- If a join-date filter is active, channels with unknown join dates are excluded.

### Input examples

#### Process known channels and videos

```json
{
  "urls": [
    "https://www.youtube.com/@Google",
    "@LinusTechTips",
    "UCXuqSBlHAE6Xw-yeJA0Tunw",
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ]
}
```

#### Discover creators by keyword

```json
{
  "searchQueries": [
    "SaaS marketing creators",
    "creator economy podcast"
  ],
  "maxResultsPerQuery": 50,
  "country": "US",
  "language": "en-US"
}
```

#### Filter by channel join date

```json
{
  "searchQueries": [
    "AI automation creators"
  ],
  "maxResultsPerQuery": 30,
  "joinedDateFrom": "2022-01-01",
  "joinedDateTo": "2026-12-31"
}
```

#### Combine direct inputs and discovery

```json
{
  "urls": [
    "https://www.youtube.com/@Google"
  ],
  "searchQueries": [
    "science education creators"
  ],
  "maxResultsPerQuery": 20
}
```

### API usage

Actor ID used in all examples:

```text
lance_api/youtube-channel-email-metadata-scraper-api
```

Set your Apify API token in the standard `APIFY_TOKEN` environment variable. Do not hard-code secrets in application source code.

#### JavaScript

Install the client:

```bash
npm install apify-client
```

Run the Actor and retrieve its dataset:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({
    token: process.env.APIFY_TOKEN,
});

const input = {
    searchQueries: ['AI automation creators'],
    maxResultsPerQuery: 20,
    country: 'US',
    language: 'en-US',
};

const run = await client
    .actor('lance_api/youtube-channel-email-metadata-scraper-api')
    .call(input);

const { items } = await client
    .dataset(run.defaultDatasetId)
    .listItems();

console.log(items);
```

#### Python

Install the client:

```bash
pip install apify-client
```

Run the Actor and iterate through its dataset:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run_input = {
    "urls": ["https://www.youtube.com/@Google"],
    "searchQueries": ["science education creators"],
    "maxResultsPerQuery": 20,
}

run = client.actor(
    "lance_api/youtube-channel-email-metadata-scraper-api"
).call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### cURL

Start a run and wait for it to finish:

```bash
curl --request POST \
  "https://api.apify.com/v2/acts/lance_api~youtube-channel-email-metadata-scraper-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "searchQueries": ["AI automation creators"],
    "maxResultsPerQuery": 20,
    "country": "US",
    "language": "en-US"
  }'
```

For larger runs, use the asynchronous Actor run endpoint and retrieve the default dataset after completion.

### Output

The Actor writes each returned record to the default dataset with a clear processing status and consistent field structure.

Output is available through:

- Apify Console
- Dataset API
- JavaScript and Python clients
- JSON, CSV, Excel, XML, RSS, and HTML exports
- Tasks, schedules, webhooks, Make, and Zapier integrations

The default Output view provides channel, contact, and performance fields. The **Contacts and links** view focuses on outreach-ready contact data.

### Complete output field reference

#### Channel identity and metadata

| Field | Type | Description |
| --- | --- | --- |
| `channelName` | string or null | Public channel title. |
| `channelHandle` | string or null | Public YouTube `@handle`. |
| `channelId` | string or null | Stable YouTube channel ID. |
| `channelUrl` | string or null | Canonical channel URL. |
| `description` | string or null | Public channel description. |
| `subscriberCount` | number or null | Normalized subscriber count. |
| `subscriberCountText` | string or null | Original subscriber-count text. |
| `viewCount` | number or null | Normalized total view count. |
| `viewCountText` | string or null | Original view-count text. |
| `videoCount` | number or null | Normalized video count. |
| `videoCountText` | string or null | Original video-count text. |
| `country` | string or null | Public channel country when available. |
| `joinedDate` | string or null | Channel join date in `YYYY-MM-DD` format. |
| `thumbnailUrl` | string or null | Channel avatar URL. |
| `bannerUrl` | string or null | Channel banner URL. |
| `isVerified` | boolean or null | Public verification state when available. |

#### Email and phone fields

| Field | Type | Description |
| --- | --- | --- |
| `youtubeEmail` | string or null | First public email returned for the channel. |
| `emails` | object\[] | All deduplicated public emails with source labels. |
| `hasEmail` | boolean | Whether at least one public email was returned. |
| `hasHiddenEmail` | boolean or null | Whether a hidden YouTube business-email option appears to exist. This is not an extracted address. |
| `phones` | object\[] | Public phone strings with source labels. |
| `hasPhone` | boolean | Whether at least one phone string was returned. |

Contact source labels can include:

- `channel-about`: channel About/description data
- `channel-description`: public channel-description text
- `channel-link`: text or URL exposed through the YouTube channel; the linked destination is not crawled

Returned emails are extracted public strings. They are not MX-, SMTP-, mailbox-, or deliverability-verified.

#### Website and social fields

| Field | Type | Description |
| --- | --- | --- |
| `websiteUrl` | string or null | Primary website when identified. |
| `instagramUrl` | string or null | Instagram profile URL. |
| `xUrl` | string or null | X/Twitter profile URL. |
| `linkedinUrl` | string or null | LinkedIn URL. |
| `facebookUrl` | string or null | Facebook URL. |
| `tiktokUrl` | string or null | TikTok URL. |
| `discordUrl` | string or null | Discord URL. |
| `telegramUrl` | string or null | Telegram URL. |
| `whatsappUrl` | string or null | WhatsApp URL. |
| `patreonUrl` | string or null | Patreon URL. |
| `skoolUrl` | string or null | Skool URL. |
| `hasLinks` | boolean | Whether any user-facing links were returned. |
| `socialLinks` | object | Links grouped by detected type. |
| `allLinks` | object\[] | All normalized links with URL, title, type, and source. |

#### Processing fields

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | Processing status: `success` or `failed`. |
| `inputUrl` | string or null | Original direct input. |
| `source` | string | Input mode: `url` or `search`. |
| `searchQuery` | string or null | Keyword that discovered the channel. |
| `scrapedAt` | ISO 8601 string | Processing timestamp. |
| `error` | string or null | Failure message when `status` is `failed`. |

### Status values

| Status | Meaning |
| --- | --- |
| `success` | Channel data was processed and returned. |
| `failed` | A direct input could not be resolved or processed. Check the `error` field for details. |

Search candidates that fail before a returnable record is created can be skipped and may not appear as failed dataset items.

### Complete output example

The example below uses reserved example contact information and does not represent a real person's private details.

```json
{
  "status": "success",
  "inputUrl": "https://www.youtube.com/@examplecreator",
  "source": "url",
  "searchQuery": null,
  "channelName": "Example Creator",
  "channelHandle": "@examplecreator",
  "channelId": "UCwx4iod3ECHlNOk9iEJB9xA",
  "channelUrl": "https://www.youtube.com/channel/UCwx4iod3ECHlNOk9iEJB9xA",
  "description": "Technology videos. Business: business@example.com",
  "subscriberCount": 125000,
  "subscriberCountText": "125K subscribers",
  "viewCount": 18400000,
  "viewCountText": "18.4M views",
  "videoCount": 312,
  "videoCountText": "312 videos",
  "country": "United States",
  "joinedDate": "2019-05-14",
  "thumbnailUrl": "https://yt3.ggpht.com/example-avatar",
  "bannerUrl": null,
  "isVerified": false,
  "youtubeEmail": "business@example.com",
  "emails": [
    {
      "email": "business@example.com",
      "source": "channel-about"
    }
  ],
  "hasEmail": true,
  "hasHiddenEmail": false,
  "phones": [],
  "hasPhone": false,
  "websiteUrl": "https://example.com/",
  "instagramUrl": "https://www.instagram.com/examplecreator/",
  "xUrl": null,
  "linkedinUrl": null,
  "facebookUrl": null,
  "tiktokUrl": null,
  "discordUrl": null,
  "telegramUrl": null,
  "whatsappUrl": null,
  "patreonUrl": null,
  "skoolUrl": null,
  "hasLinks": true,
  "socialLinks": {
    "website": ["https://example.com/"],
    "instagram": ["https://www.instagram.com/examplecreator/"]
  },
  "allLinks": [
    {
      "url": "https://example.com/",
      "title": "Website",
      "type": "website",
      "source": "channel-link"
    },
    {
      "url": "https://www.instagram.com/examplecreator/",
      "title": "Instagram",
      "type": "instagram",
      "source": "channel-link"
    }
  ],
  "scrapedAt": "2026-01-01T00:00:00.000Z",
  "error": null
}
```

### 💰 Pricing

This Actor uses **pay-per-event pricing**.

- **Keyword search:** $0.05 per submitted search query.
- **Email found:** When a returned channel contains at least one public email, an `email-found` fee applies. The fee is charged **once per channel result, not once per email**: whether a channel contains one public email or several, it counts as one email-found event.
- **No public email found:** No `email-found` fee is charged.
- **Phone numbers:** Public phone numbers may be included when available. Finding a phone number does **not** trigger an additional charge.

See the Actor's **Pricing** tab for the current email-found price, Store discounts, and platform charges applicable to your plan.

### 🎯 Use cases

#### Creator outreach

Build contact-ready YouTube creator lists containing public emails, phone numbers, websites, social profiles, and channel statistics.

#### Influencer discovery

Search by topic or niche, identify relevant channels, and enrich every returned creator record.

#### Sponsorship prospecting

Use audience size, channel activity, geography, public links, and contact availability to prioritize partnership candidates.

#### Lead generation

Turn channel, handle, and video lists into structured records for qualification and outreach workflows.

#### CRM enrichment

Add stable channel IDs, handles, public contacts, social profiles, subscriber counts, country, join dates, and processing timestamps to existing creator records.

#### Market and competitor research

Analyze public YouTube channel data across niches, localized searches, creator segments, and markets.

#### Developer and AI automation

Connect the Actor to applications, data warehouses, agent workflows, Tasks, schedules, webhooks, Make, Zapier, or custom APIs.

### Public data and responsible use

This Actor is designed for responsible workflows involving publicly available YouTube channel data.

- It extracts email addresses only from supported **public channel sources**.
- It does not access private accounts, private content, or non-public user information.
- It does not bypass YouTube login, sign-in, or verification walls.
- It does not solve CAPTCHA or reCAPTCHA challenges.
- It does not reveal email addresses hidden behind YouTube's verification flow.
- It does not visit linked external websites to search for additional contact information.
- It does not validate whether an email mailbox exists or is deliverable.

You are responsible for complying with YouTube's Terms of Service, Apify's Terms of Service, applicable privacy and anti-spam laws, and any other rules relevant to your use case.

If you use contact data for outreach, review requirements under CAN-SPAM, GDPR, ePrivacy, and applicable local regulations. Do not use the Actor for spam, harassment, unlawful profiling, or attempts to access non-public information.

### FAQ

#### Does this Actor return every YouTube business email?

No. It returns public email strings available through supported channel-level data. YouTube can place business emails behind login and verification flows that this Actor does not bypass.

#### What does `hasHiddenEmail` mean?

It means YouTube appears to show a business-email option for the channel. It does not mean the address was revealed or returned.

#### Why did a channel return no email?

Many channels do not publish an email publicly. In that case, `hasEmail` is `false`, `youtubeEmail` is `null`, and `emails` is empty. You pay no email-found fee for that result.

#### Are the returned emails verified?

No. They are extracted public strings, not deliverability-verified mailboxes.

#### Can I submit a video or Shorts URL?

Yes. The Actor resolves the uploader channel and returns channel-level contact information and metadata.

#### Can I combine direct inputs and keyword search?

Yes. Both modes can run together. Search-discovered channels are deduplicated by stable channel ID.

#### How does keyword search pricing work?

Keyword discovery costs $0.05 per submitted query. Returned channels do not incur a separate per-result charge in the current implementation. The email-found fee applies only to channel results containing at least one public email, and finding a phone number does not trigger an additional charge.

#### How are duplicate inputs handled?

Each non-empty direct input is processed independently. Search-discovered channels are deduplicated by stable channel ID.

#### Does the Actor scan external websites, video descriptions, or pinned comments?

No. The current version focuses on supported channel-level data and does not crawl linked destinations, video descriptions, or pinned comments.

#### Why can `websiteUrl` be null when `allLinks` contains values?

`websiteUrl` is reserved for a link classified as a primary website. Social or other links can remain in `allLinks` without being assigned to that field.

#### How can I control run cost?

Set the maximum charge limit when starting the run, reduce `maxResultsPerQuery`, and test with a small input first.

### Limitations

- Only publicly available YouTube channel data is supported.
- Private, deleted, restricted, renamed, blocked, or temporarily unavailable channels can fail.
- Some fields can be `null` when the channel does not publish them.
- Hidden business-email indicators do not contain the hidden email address.
- Public email strings are not mailbox- or deliverability-verified.
- Linked external websites are not crawled.
- Video descriptions and pinned comments are not scanned.
- Search localization influences relevance but does not guarantee channel country or content language.
- Join-date filtering excludes channels whose join date is unknown.
- Search may return fewer items than `maxResultsPerQuery`. The value is only a maximum; a successful provider can legitimately return fewer channels, and that alone does not trigger fallback to another provider. Filters, duplicates, or unavailable channels can reduce the final count further.
- Temporary YouTube, network, or page-structure changes can affect availability.
- Search candidates that fail before a returnable record is created may be skipped rather than written as failed items.

### 🛠️ Support

Need help, want to report an issue, or have a feature request?

- Open the Actor's **Issues** tab in Apify Console
- Email **support@apismith.online**

For the fastest diagnosis, include the run ID and a non-sensitive example input. Never send your Apify API token.

### Internal observability (Actor Observability V3.0)

This Actor supports the internal Actor Observability V3.0 reporter. Observability is fail-open and does not change Actor input, output, pricing, provider priority, retry behavior, or user-visible errors.

Environment variables:

- `ACTOR_ISSUE_LOG_URL` — observability ingest endpoint.
- `ACTOR_ISSUE_LOG_KEY` — secret authentication key. Configure only as an Apify secret/environment variable; never commit it.
- `ACTOR_ISSUE_LOG_ENABLED=true` — report failed and non-perfect executions.
- `ACTOR_RESULT_LOG_ENABLED=true` — report all final input events, including perfect successes.
- `ACTOR_BUSINESS_INSIGHT_LOG_ENABLED=false` — optional opt-out; business insight logging is enabled by default.

V3 records one final event per direct input or search-query input and structures details into `humanSummary`, `diagnostics`, and `businessInsight`. Search HTTP attempts and channel-enrichment operations are counted separately; the Actor does not fabricate raw HTTP-attempt counts for requests hidden inside an internal library.

# Actor input Schema

## `urls` (type: `array`):

YouTube channel URLs, @handles, channel IDs, custom channel URLs, user URLs, or video URLs. Each non-empty direct input is processed independently.

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

Keywords used to discover YouTube channels. Each submitted keyword has a $0.05 discovery fee. Returned channels do not incur a separate per-result charge; an additional fee applies only when a returned channel contains a public email.

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

Maximum number of channels each keyword may return after enrichment and joined-date filtering. This is an upper bound, not a minimum target: if a search provider succeeds with fewer channels, the Actor accepts those results and does not call another provider just to fill the remaining quantity.

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

Localize keyword search results. Ignored for direct URL input. This affects search relevance only and does not remove returned channels by country.

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

Localize keyword search results. Ignored for direct URL input.

## `joinedDateFrom` (type: `string`):

Skip channels created before this date. Leave empty to include all. Use YYYY-MM-DD.

## `joinedDateTo` (type: `string`):

Skip channels created after this date. Leave empty to include all. Use YYYY-MM-DD.

## Actor input object example

```json
{
  "urls": [
    "https://www.youtube.com/@Google"
  ],
  "maxResultsPerQuery": 20,
  "country": "",
  "language": ""
}
```

# Actor output Schema

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

Public contact details, YouTube channel metadata, source context, and processing status.

# 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 = {
    "urls": [
        "https://www.youtube.com/@Google"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lance_api/youtube-channel-email-metadata-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 = { "urls": ["https://www.youtube.com/@Google"] }

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

```

## MCP server setup

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