# YouTube Channel Search Scraper (`vakitek/youtube-channel-search`) Actor

Find YouTube creators by keyword. Subscriber count, handle, description and verified badge for every channel, with filters for minimum/maximum subscribers and verified-only. 1.00 USD per 1,000 channels, no minimum charge per run.

- **URL**: https://apify.com/vakitek/youtube-channel-search.md
- **Developed by:** [Brahim Sliti](https://apify.com/vakitek) (community)
- **Categories:** Social media, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 channel results

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 Search Scraper

Give it a keyword, get back the YouTube channels that match it. You get one row per channel: name, handle, URL, subscriber count, description and verified badge.

You only pay for channels that pass your filters. A channel removed by a subscriber range or by "verified only" never reaches your dataset, and is never charged.

### What people use it for

- **Creator discovery for a niche.** Search "coffee roasting" and get every channel talking about it, ranked the same way YouTube's own search ranks them.
- **Building an influencer shortlist.** Set a minimum subscriber count so only channels big enough to matter come back.
- **Checking which creators in a space are verified.** Turn on "Verified channels only" to skip personal or small accounts.
- **Watching several related keywords in one run.** Add a few search terms at once; a channel that matches more than one still only costs you once.

### How to use it

1. Add your keywords in **Search terms**, one per line, just like you would type them into YouTube's search bar.
2. Set **Max channels per search term** (default 50).
3. Optionally set **Minimum subscribers**, **Maximum subscribers**, **Verified channels only**, or **Exclude these channels** (handles or ids, always free).
4. Click **Start**. Export as JSON, CSV or Excel, or pull the results through the API.

```json
{
  "searchTerms": ["coffee roasting"],
  "maxChannelsPerSearchTerm": 50,
  "minSubscribers": 10000
}
```

### What you get

```json
{
  "channelId": "UCSJAOU3yrZztkTYQNKKKq1g",
  "channelName": "Coffee | One Roast at a Time",
  "channelHandle": "@CoffeeOneRoastataTime",
  "channelUrl": "https://www.youtube.com/@CoffeeOneRoastataTime",
  "description": "Home coffee roasting with the Gene Cafe CBR-301.",
  "numberOfSubscribers": 154,
  "subscriberCountText": "154 subscribers",
  "channelTotalVideos": null,
  "isVerified": false,
  "avatarUrl": "https://yt3.ggpht.com/avatar.jpg",
  "searchTerm": "coffee roasting",
  "rank": 1
}
```

- `numberOfSubscribers`: `null` only when YouTube's own search result did not carry a subscriber count at all, never a guess.
- `channelTotalVideos`: usually `null` on a plain search result. Turn on **Add About data** below to fill it in from the channel's own About page.
- `searchTerm`/`rank`: which of your search terms first found this channel, and its position in that term's results. A channel matching several terms keeps the term and rank of its first hit only.
- `isVerified`: YouTube's verified (check mark) badge.

#### Add About data (optional)

Turning on **Add About data: total views, joined date, country, links** adds `channelTotalViews`, `channelJoinedDate`, `channelLocation` and `channelDescriptionLinks` to every channel, from one extra request per channel, at no extra charge.

### Pricing

**1.00 USD per 1,000 channels.** A channel removed by a filter, or seen again under a later search term, is never returned and never charged. Error rows are also free.

No monthly fee, no charge for the Apify platform usage on top. Example: 2 search terms with 50 channels each, all passing your filters and none overlapping, costs 100 x 0.001 = 0.10 USD.

### Good to know

- Subscriber counts are read from YouTube's own search result text, the same text you would see on youtube.com.
- Filters (subscribers, verified) are applied to YouTube's channel search results, which are ranked by relevance, not size. A narrow filter can return fewer channels than asked: you then get a free `NO_MORE_RESULTS` row saying how many matched.
- You don't need a proxy or a YouTube account.
- Looking for a channel's videos instead of the channel itself? See `youtube-channel-videos`. Looking for a channel's email? See `youtube-channel-email`.

### Use it from n8n, Make or an API

- **Small inputs**: call `run-sync-get-dataset-items` and read the items back directly. Set **Time budget (seconds)** (default 240) to how long you are willing to wait: the actor stops starting new search terms before that point and returns what it already has, so you never hit Apify's 300 second run-sync limit and lose the whole run. A term left unfinished comes back as a `TIME_BUDGET_EXCEEDED` row instead of being silently dropped.
- **Big inputs**: start the run with `POST /v2/acts/vakitek~youtube-channel-search/runs`, poll `GET /v2/actor-runs/<runId>` (or add `waitForFinish=60`) until the status is `SUCCEEDED`, then read `GET /v2/datasets/<datasetId>/items`. Set **Time budget (seconds)** to `0` (no limit) for this pattern.

### Errors

A bad input never crashes the run. It becomes a row with an `error` code, and you are not charged for it.

| `error` | What happened | Retry? |
| --- | --- | --- |
| `NO_RESULTS` | A search term matched no channel | No |
| `NO_MORE_RESULTS` | Your filters left fewer channels than you asked for, after scanning YouTube's results for that term (free, the channels found are still delivered) | No |
| `INVALID_INPUT` | A search term or option value is invalid | No |
| `BLOCKED` | YouTube refused us for now, even after trying every proxy tier | Yes |
| `UPSTREAM_ERROR` | Something went wrong on YouTube's side or ours | Yes |
| `UPSTREAM_UNAVAILABLE` | Our API was unreachable | Yes |
| `TIME_BUDGET_EXCEEDED` | The time budget ran out before this search term finished | Yes |

### FAQ

**I already use another YouTube channel search actor. Do I have to change my code?**
Probably not much. We use the same keyword-based search and the same output fields buyers care about: `channelId`, `channelName`, `channelHandle`, `numberOfSubscribers`, `isVerified`.

**Can I call it from my code or from an AI agent?**
Yes, like any Apify actor: REST API, the Python and JavaScript clients, or the Apify MCP server. The examples are in the API tab.

**Something broke or a result looks wrong?**
Open an issue on this page. We read every one and usually answer within a day.

# Changelog

This Actor's version history is a separate document: https://apify.com/vakitek/youtube-channel-search/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

Enter search terms just like you would enter them in YouTube's search bar. Each term is searched for channels, not videos.

## `maxChannelsPerSearchTerm` (type: `integer`):

Maximum number of channels to return per search term.

## `maxTotalResults` (type: `integer`):

Caps the whole run across every search term, on top of the per-term limit above. Leave empty for no extra cap.

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

Only return channels with at least this many subscribers.

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

Only return channels with at most this many subscribers.

## `verifiedOnly` (type: `boolean`):

Only return channels with YouTube's verified badge.

## `excludedChannels` (type: `array`):

Handles or channel ids to skip, even if a search term matches them. Always free.

## `includeChannelDetails` (type: `boolean`):

Adds channelTotalViews, channelJoinedDate, channelLocation and channelDescriptionLinks to every channel. Same price.

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

Interface language (hl) requested from YouTube, as an ISO 639-1 code (e.g. fr, de, ja).

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

Geolocation (gl) requested from YouTube, as an ISO 3166-1 alpha-2 code (e.g. FR, DE, JP).

## `timeBudgetSecs` (type: `integer`):

Stop and return what is ready after this many seconds, so n8n/Make run-sync calls never time out. 0 = no limit.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee roasting"
  ],
  "maxChannelsPerSearchTerm": 50,
  "verifiedOnly": false,
  "excludedChannels": [],
  "includeChannelDetails": false,
  "language": "en",
  "country": "US",
  "timeBudgetSecs": 240
}
```

# Actor output Schema

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

Channels found by the search terms, with subscriber count, handle, description and verified badge. Error items carry an `error` code and the `input` that failed.

# 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 = {
    "searchTerms": [
        "coffee roasting"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vakitek/youtube-channel-search").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 = { "searchTerms": ["coffee roasting"] }

# Run the Actor and wait for it to finish
run = client.actor("vakitek/youtube-channel-search").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 '{
  "searchTerms": [
    "coffee roasting"
  ]
}' |
apify call vakitek/youtube-channel-search --silent --output-dataset

```

## MCP server setup

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

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/nQ8I6h99bpWgBkl7F/builds/UuSH49JbTdC8TAKIv/openapi.json
