# YouTube Shorts Scraper (`beautifulscrape/youtube-shorts`) Actor

Extract YouTube Shorts data from one or multiple YouTube channels. Get video URL, caption, timestamp, likes, views, comments count, and channel info.

- **URL**: https://apify.com/beautifulscrape/youtube-shorts.md
- **Developed by:** [Beautiful Scrape](https://apify.com/beautifulscrape) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 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

## What is YouTube Shorts Scraper?

YouTube Shorts Scraper lets you extract Shorts data from YouTube channels, individual Short URLs, and hashtags — helping you track trends, analyze engagement, and gather content insights with just a few clicks.

**Find current trends**: discover what Shorts creators are posting and which topics are getting traction
**Analyze engagement**: extract views, likes, comments counts, and upload dates to compare performance across channels
**Monitor competitors**: track Shorts activity on competitor channels and see how their short-form content performs
**Scrape by hashtag**: collect Shorts tagged with a specific topic via YouTube's hashtag Shorts tab
**Automate Shorts collection**: replace manual browsing with repeatable workflows that keep datasets fresh and consistent

The scraper can open a channel’s Shorts tab, fetch a direct Short URL, or browse a hashtag’s Shorts page — then enrich each Short with detailed metadata beyond what the YouTube Data API makes easy to collect in bulk.

### What data does YouTube Shorts Scraper extract?

📝 **Title** - The Shorts video title / caption

🆔 **Video ID** - The unique YouTube video ID

🔗 **URL** - Direct link to the Short (`https://www.youtube.com/shorts/...`)

👁️ **View Count** - Number of views on the Short

📅 **Date** - Upload date of the Short

👍 **Likes** - Number of likes on the Short

⏱️ **Duration** - Length of the Short

💬 **Comments Count** - Total number of comments on the Short

📺 **Channel Name** - Name of the channel that posted the Short

🌐 **Channel URL** - Link to the channel page

📈 **Subscribers** - Number of channel subscribers

🖼️ **Thumbnail URL** - Thumbnail image for the Short

\#️⃣ **Hashtags** - Hashtags associated with the Short

📄 **Text** - Full description / caption text

🏷️ **Type** - Always `"shorts"` for items from this actor

### Features

For maximum usefulness, YouTube Shorts Scraper has the following abilities:

**Extract everything**: Shorts metadata, engagement metrics, descriptions, hashtags, and channel details

**Flexible input**: scrape from channels, direct Short URLs, and/or hashtags in one run

**Result limit**: control how many Shorts to scrape per channel or hashtag with `maxResultsShorts`

**Sorting options**: choose newest, most popular, or oldest Shorts on the channel tab

**Date filtering**: scrape only Shorts published after a specific date with `oldestPostDate`

**Automatic pagination**: handles Shorts tab continuation pages automatically

**Error resilience**: continues processing remaining inputs even if one fails

**Structured output**: export data in JSON format with consistent schema for easy analysis

### ⬇️ Input

Provide at least one of: channels, Short URLs, or hashtags. You can also configure the maximum number of Shorts, sorting preferences, and date filters. You can set up the input programmatically or use the fields in the Actor's interface.

#### Channels

You can provide one or more YouTube channels using the `channels` array. Each entry can be a username (with or without `@`) or a full channel URL.

**Supported channel formats**:

- Username: `nasa`
- Handle: `@nasa`
- Channel URL: `https://www.youtube.com/@nasa`
- Shorts tab URL: `https://www.youtube.com/@nasa/shorts`
- Channel ID URL: `https://www.youtube.com/channel/UCxxx`
- Custom URL: `https://www.youtube.com/c/Apify`

#### Short URLs

Use `shortUrls` to scrape one or more Shorts directly by URL.

**Supported URL formats**:

- Shorts: `https://www.youtube.com/shorts/VIDEO_ID`
- Watch: `https://www.youtube.com/watch?v=VIDEO_ID`
- Short link: `https://youtu.be/VIDEO_ID`

#### Hashtags

Use `hashtags` to scrape Shorts from a hashtag’s Shorts tab (`https://www.youtube.com/hashtag/{tag}/shorts`).

**Supported formats**:

- `gaming`
- `#gaming`
- `https://www.youtube.com/hashtag/gaming`
- `https://www.youtube.com/hashtag/gaming/shorts`

#### Input Parameters

Provide **at least one** of:

- `channels` (array) - YouTube channel usernames or URLs
- `shortUrls` (array) - Direct Short / video URLs
- `hashtags` (array) - Hashtags to scrape Shorts from

**Optional:**

- `maxResultsShorts` (integer, default: 10) - Limit Shorts per channel or hashtag (Short URLs always return one item each)
- `sortChannelShortsBy` (string, default: `"NEWEST"`) - Channel Shorts tab sorting only:
  - `"NEWEST"` = Newest Shorts first
  - `"POPULAR"` = Most popular Shorts first
  - `"OLDEST"` = Oldest Shorts first
- `oldestPostDate` (string) - Only Shorts uploaded after or on this date will be scraped (channels and hashtags). Putting `"1 day"` gets today's Shorts, `"2 days"` yesterday's and today's, and so on. When set, channel sorting is auto-reset to newest.

#### Example Input (channels)

```json
{
  "channels": ["nasa", "vsauce"],
  "maxResultsShorts": 25,
  "sortChannelShortsBy": "NEWEST"
}
```

#### Example Input (Short URL)

```json
{
  "shortUrls": [
    "https://www.youtube.com/shorts/myZ9kn9MIWQ"
  ]
}
```

#### Example Input (hashtag)

```json
{
  "hashtags": ["gaming", "#ai"],
  "maxResultsShorts": 20
}
```

#### Example Input (combined)

```json
{
  "channels": ["mrbeast"],
  "shortUrls": ["https://www.youtube.com/shorts/myZ9kn9MIWQ"],
  "hashtags": ["fashion"],
  "maxResultsShorts": 10
}
```

#### Example Input with Date Filter

```json
{
  "channels": ["nasa"],
  "maxResultsShorts": 50,
  "oldestPostDate": "2025-06-03",
  "sortChannelShortsBy": "NEWEST"
}
```

### ⬆️ Output

The results will be wrapped into a dataset which you can find in the Output or Storage tab. Note that the output is organized in tables and tabs for viewing convenience. You can view results as a table, JSON, or other formats.

Once the run is finished, you can also download the dataset in various data formats (JSON, CSV, Excel, XML, HTML). Before exporting, you can pick or omit specific output fields.

#### Table View

The table view displays all Shorts with their associated metadata. You can sort by title, views, date, likes, channel name, or other fields.

#### JSON Output

Here's an example of the data structure for a single Short:

```json
{
  "title": "2026 Solar Eclipse @ 50,000 Feet",
  "type": "shorts",
  "id": "myZ9kn9MIWQ",
  "url": "https://www.youtube.com/shorts/myZ9kn9MIWQ",
  "thumbnailUrl": "https://i.ytimg.com/vi/myZ9kn9MIWQ/maxresdefault.jpg",
  "viewCount": 256184,
  "date": "2026-08-14T00:00:00.000Z",
  "likes": 13760,
  "location": null,
  "channelName": "NASA",
  "channelUrl": "https://www.youtube.com/channel/UCLA_DiR1FfKNvjuUpBHmylQ",
  "channelId": "UCLA_DiR1FfKNvjuUpBHmylQ",
  "channelUsername": "NASA",
  "numberOfSubscribers": 15100000,
  "duration": "01:33",
  "commentsCount": null,
  "text": "These views, including footage from GoPro cameras, were captured by NASA's WB-57 aircraft during the 2026 total solar eclipse.",
  "hashtags": [],
  "fromYTUrl": "https://www.youtube.com/@nasa/shorts",
  "fromChannelListPage": "shorts",
  "order": 0,
  "input": "nasa"
}
```

#### Output Fields

| Field | Type | Description |
|-------|------|-------------|
| `title` | string | null | The Shorts video title / caption |
| `type` | string | Always `"shorts"` |
| `id` | string | The unique YouTube video ID |
| `url` | string | Direct link to the Short |
| `thumbnailUrl` | string | null | Thumbnail image URL |
| `viewCount` | number | null | Number of views on the Short |
| `date` | string | null | Upload date (ISO format) |
| `likes` | number | null | Number of likes on the Short |
| `duration` | string | null | Length of the Short |
| `commentsCount` | number | null | Total number of comments |
| `text` | string | null | Full description / caption text |
| `hashtags` | array | Hashtags found in the Short description |
| `hashtag` | string | null | Source hashtag when scraped via `hashtags` input |
| `channelName` | string | null | Name of the channel |
| `channelUrl` | string | null | Link to the channel page |
| `channelId` | string | null | YouTube channel ID |
| `channelUsername` | string | null | Channel handle / username |
| `numberOfSubscribers` | number | null | Number of channel subscribers |
| `fromYTUrl` | string | The Shorts / hashtag / Short URL that was scraped |
| `fromChannelListPage` | string | null | `"shorts"` when scraped from a channel tab |
| `order` | number | 0-based position in the results |
| `input` | string | Original input value (channel, URL, or hashtag) |

### Error items

When the scraper cannot retrieve data for a given input — for example a channel does not exist or has no Shorts — it pushes an error item to the dataset instead of silently skipping it. Normal output items are never affected; you can tell them apart by the presence of an `error` field.

#### Error item structure

```json
{
  "url": "https://www.youtube.com/@somechannel",
  "input": "somechannel",
  "error": "CHANNEL_HAS_NO_SHORTS",
  "note": "The channel has no shorts."
}
```

#### Error codes reference

| Error code | Meaning |
|---|---|
| `CHANNEL_DOES_NOT_EXIST` | Channel URL points to a channel that does not exist |
| `CHANNEL_HAS_NO_SHORTS` | Channel exists but has no Shorts |
| `DATE_FILTER_TOO_STRICT` | Shorts exist but none match the active date filter |
| `NO_VIDEOS` | No Shorts found for the hashtag |
| `VIDEO_UNAVAILABLE` | Short URL is unavailable or deleted |
| `NOT_FOUND` | Page was not found |
| `INVALID_INPUT` | Actor failed due to bad configuration |

# Actor input Schema

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

Enter a username of a channel (without @ sign) or a link to it (e.g. https://www.youtube.com/@nasa or https://www.youtube.com/c/Apify).

## `shortUrls` (type: `array`):

Direct YouTube Short URLs to scrape individually. Also accepts watch URLs and youtu.be links.

## `hashtags` (type: `array`):

Hashtags to scrape Shorts from (with or without #). Uses YouTube's hashtag Shorts tab, e.g. https://www.youtube.com/hashtag/gaming/shorts.

## `maxResultsShorts` (type: `integer`):

Limit the number of Shorts to crawl per channel or hashtag. Short URLs always return one item each.

## `oldestPostDate` (type: `string`):

Only posts uploaded after or on this date will be scraped. Alternatively, specify how old the scraped videos should be in days. Putting '1 day' will get you only today's posts, '2 days' - yesterday's and today's, and so on. Note that if you select this, sorting parameter will be auto-reset to NEWEST. Applies to channels and hashtags.

## `sortChannelShortsBy` (type: `string`):

Maps to the three sorting buttons on the top of the channel Shorts page. Only applies when scraping by channel.

## Actor input object example

```json
{
  "channels": [
    "nasa"
  ],
  "shortUrls": [
    "https://www.youtube.com/shorts/myZ9kn9MIWQ"
  ],
  "hashtags": [
    "gaming"
  ],
  "maxResultsShorts": 10,
  "sortChannelShortsBy": "NEWEST"
}
```

# 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": [
        "nasa"
    ],
    "shortUrls": [
        "https://www.youtube.com/shorts/myZ9kn9MIWQ"
    ],
    "hashtags": [
        "gaming"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("beautifulscrape/youtube-shorts").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": ["nasa"],
    "shortUrls": ["https://www.youtube.com/shorts/myZ9kn9MIWQ"],
    "hashtags": ["gaming"],
}

# Run the Actor and wait for it to finish
run = client.actor("beautifulscrape/youtube-shorts").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": [
    "nasa"
  ],
  "shortUrls": [
    "https://www.youtube.com/shorts/myZ9kn9MIWQ"
  ],
  "hashtags": [
    "gaming"
  ]
}' |
apify call beautifulscrape/youtube-shorts --silent --output-dataset

```

## MCP server setup

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

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/j4elPXFEG81qUbkMi/builds/AIR9KNP2N6GWU6MKt/openapi.json
