# YouTube Shorts Finder Pro — Search, Channels & Hashtags (`dami0089/youtube-shorts-finder-pro`) Actor

Buscá Shorts por canal, keyword, hashtag o URL. Metadata exacta + viral score y engagement. Sin login, sin API key, a mitad de precio del scraper oficial.

- **URL**: https://apify.com/dami0089/youtube-shorts-finder-pro.md
- **Developed by:** [Damian Oliva](https://apify.com/dami0089) (community)
- **Categories:** Videos, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 Shorts Finder Pro — Search, Channels & Hashtags

Find **any YouTube Short** by channel, keyword, hashtag, or direct URL — with views, displayed likes and comment counts, hashtags, plus a **viral score** and **engagement rate** on every row. No login, no API key, no quotas.

### What it does

YouTube Shorts are where the views are, but YouTube search and channel pages make Shorts discoverable. This actor scrapes Shorts in **4 input modes with per-line auto-detection**:

1. **Channel** — `@handle`, `youtube.com/channel/…`, `/c/…` or `/user/…` URLs. Reads the channel's Shorts tab (with pagination).
2. **Keyword** — any YouTube search (`cooking tips`), filtered to the Shorts shelf (with pagination).
3. **Hashtag** — `#asmr` and friends, resolved through YouTube search so you get real Shorts, not long-form videos.
4. **Direct URL** — paste a `youtube.com/shorts/<id>` (or `watch?v=`, `youtu.be/`) link to enrich one specific video.

Every Short comes back with: video id, URL, title, full description, hashtags, view counts and displayed like/comment counts, duration in seconds, ISO publish date, thumbnail, caption availability, comments-disabled flag, channel data (id, name, URL, subscribers, verified badge) — plus two computed metrics:

- **viralScore** = `viewCount / channelSubscribers` — how many times over its own audience a Short went. A score above 1.0 means it broke out of the channel's subscriber base.
- **engagementRate** = `(likeCount + commentCount) / viewCount` — likes and comments per view.

Optional **top comments** per Short (author, text, likes, replies, publish time).

### How to use it

1. Add one entry per line in **Channels, keywords, hashtags or Shorts URLs**: channels (`@MrBeast`), plain keywords (`cooking tips`), hashtags (`#asmr`), or Shorts URLs.
2. Set **Max Shorts per entry** (`maxResults`, 1–1000) and the **global cap** (`maxItems`) to control spend.
3. Optionally filter by date (**Published after** accepts `2026-01-01` or relative values like `7 days`, `2 weeks`, `1 month` — free, no extra charge), pick the **sort order** (`newest`, `popular`, `oldest`), and enable **top comments**.
4. Run. Results land in the default dataset; comments land in the same dataset with `type: "comment"`. Failed inputs are reported as typed error items (`CHANNEL_NOT_FOUND`, `NO_SHORTS`, `DATE_FILTER_EMPTY`, `VIDEO_UNAVAILABLE`) in the default dataset and summarized in the `ERRORS` key-value record — the run never dies because of one bad line.

#### Example input

```json
{
  "maxResults": 5,
  "sortOrder": "newest",
  "startUrls": ["@MrBeast"]
}
```

#### Example output (real run)

```json
{
  "videoId": "aNI2jv7lBPQ",
  "url": "https://www.youtube.com/shorts/aNI2jv7lBPQ",
  "title": "Giving $10,000 To A Random Subscriber",
  "description": null,
  "hashtags": [],
  "viewCount": 19211316,
  "likeCount": 604000,
  "commentCount": 14000,
  "durationSeconds": 40,
  "publishedAt": "2026-10-09T16:00:01.000Z",
  "thumbnail": "https://i.ytimg.com/vi/aNI2jv7lBPQ/hqdefault.jpg",
  "captionsAvailable": true,
  "commentsDisabled": false,
  "viralScore": 0.03687392706333973,
  "engagementRate": 0.03216854066634477,
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "channelName": "MrBeast",
  "channelUrl": "https://www.youtube.com/@MrBeast",
  "channelSubscribers": 521000000,
  "channelVerified": true,
  "source": "channel",
  "query": "@MrBeast",
  "scrapedAt": "2026-10-12T07:21:49.240Z"
}
```

Use cases: find viral Shorts in your niche, track competitors' Shorts output, harvest proven hooks and hashtags, measure which topics break out (viralScore > 1), or enrich a list of Shorts URLs with public stats.

### Pricing

Pay per event — you only pay for data you receive:

| Event | Price (USD) | What counts |
|---|---|---|
| `short` | $0.002 | Each Short with full metadata, viral score and engagement rate |
| `comment` | $0.0004 | Each top comment (only when top-comments mode is on) |

Typical runs:

- 100 Shorts from one channel ≈ **$0.20**
- 1,000 Shorts across 10 keywords ≈ **$2.00**
- 50 Shorts with 20 comments each (50 shorts + 1,000 comments) ≈ **$0.50**

Date filtering, sorting, deduplication and error reporting have no separate event charge.

### How it compares

Channel-only Shorts scrapers exist (including the official one). This actor differs in measurable ways:

| | This actor | Typical channel-only scrapers |
|---|---|---|
| Inputs | Channels, keywords, hashtags, direct URLs | Channels only |
| Discovery | Search YouTube for any topic/hashtag | Limited to channels you already know |
| Date filter | Included free | Often a separately billed extra |
| Derived metrics | viralScore + engagementRate per row | Raw counts only |
| Price per Short | $0.002 | Up to 2× more |
| Engine | Plain HTTP, no browser (fewer failure points) | Often headless browsers |

Metadata is parsed from YouTube's public pages; unavailable fields are null. Rounded counts (likes, comments or subscribers shown as `2.6K` by YouTube itself) are returned as their numeric value (2600).

### FAQ

**Is this legal / against YouTube's terms?** The actor only reads public pages (the same HTML any logged-out browser receives). It needs no login, no API key, and optional comment rows include public author names, channel IDs and avatars. Respect YouTube's Terms of Service for your use case.

**How accurate are the numbers?** Views come from the public watch page. Likes, comment counts and subscriber counts may be rounded by YouTube (for example, `14K` comments becomes `14000`). Derived metrics use those displayed numbers. Missing counts are `null`.

**How is pagination handled?** Channel tabs, search shelves and hashtag results are paginated with continuation tokens until `maxResults` per entry or the global `maxItems` cap is reached.

**Which region are results from?** Requests run with US/English locale. YouTube still personalizes some ordering by proxy egress region; search/hashtag modes follow YouTube relevance order unless you sort `newest`/`popular`/`oldest` after collection.

**Why did an entry return an error item?** `CHANNEL_NOT_FOUND` (bad handle/URL), `NO_SHORTS` (valid page, no Shorts found), `DATE_FILTER_EMPTY` (Shorts exist but all are older than your filter — loosen `publishedAfter`), `VIDEO_UNAVAILABLE` (deleted/private video). Other lines still run.

**Do I need proxies?** YouTube blocks datacenter IPs, so the actor defaults to Apify Residential proxies (changeable in the input). It retries with exponential backoff on 429/5xx and keeps going when a single video fails.

**Comments?** Turn on *Include top comments* to get up to `maxComments` (1–200) top-level comments per Short, billed as `comment` events in the default dataset. Videos with disabled comments are flagged (`commentsDisabled: true`, `commentCount: null`).

### Integrations

- **Apify API**: run via `POST /v2/acts/<actor-id>/runs`, read `defaultDatasetId` items; comments in the same dataset.
- **Make / Zapier / n8n**: use the Apify integration, trigger on dataset items.
- **AI agents (MCP)**: the dataset has a table view (`overview`) and a fixed schema, so agents can query Shorts by views, viral score or hashtag directly.

### Support

Found a page layout this actor misreads, or hitting blocks at scale? Open a run with a minimal input that reproduces it (one line in `startUrls`) and describe what you expected — layout fixes ship fast because parsing is defensive and covered by tests.

# Actor input Schema

## `startUrls` (type: `array`):

One entry per line. Each line is auto-detected: channels (@handle, /channel/, /c/ URLs), keywords (YouTube search filtered to Shorts), #hashtags, or direct Shorts URLs to enrich a specific video.

## `maxResults` (type: `integer`):

Maximum Shorts collected for each input entry (1-1000). Direct Shorts URLs return that video.

## `maxItems` (type: `integer`):

Global cap of Shorts per run, to control spend. Stops collecting once reached.

## `publishedAfter` (type: `string`):

Only Shorts published after this date. Absolute (YYYY-MM-DD) or relative ('7 days', '2 weeks', '1 month'). Free, no extra charge.

## `sortOrder` (type: `string`):

Result order per input entry: newest, popular (by views) or oldest.

## `includeComments` (type: `boolean`):

When enabled, scrapes the top comments of each Short (billed as separate comment events).

## `maxComments` (type: `integer`):

Top comments scraped per Short when includeComments is on (1-200).

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

YouTube blocks datacenter IPs: use Residential proxies.

## Actor input object example

```json
{
  "startUrls": [
    "@MrBeast",
    "cooking tips",
    "#asmr",
    "https://www.youtube.com/shorts/dQw4w9WgXcQ"
  ],
  "maxResults": 5,
  "maxItems": 100,
  "publishedAfter": "2026-01-01",
  "sortOrder": "newest",
  "includeComments": false,
  "maxComments": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Shorts with full metadata, viral score and engagement rate. Open the dataset items table.

# 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 = {
    "startUrls": [
        "@MrBeast"
    ],
    "maxResults": 5,
    "maxItems": 100,
    "sortOrder": "newest",
    "includeComments": false,
    "maxComments": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami0089/youtube-shorts-finder-pro").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 = {
    "startUrls": ["@MrBeast"],
    "maxResults": 5,
    "maxItems": 100,
    "sortOrder": "newest",
    "includeComments": False,
    "maxComments": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("dami0089/youtube-shorts-finder-pro").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 '{
  "startUrls": [
    "@MrBeast"
  ],
  "maxResults": 5,
  "maxItems": 100,
  "sortOrder": "newest",
  "includeComments": false,
  "maxComments": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call dami0089/youtube-shorts-finder-pro --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami0089/youtube-shorts-finder-pro"
        }
    }
}
```

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/xmJidQgYcX5EtotW5/builds/RdgA1M3pvMTl0OhJu/openapi.json
