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

Scrape public Shorts from YouTube channels with video metrics, dates, captions, and channel details.

- **URL**: https://apify.com/mlg14/youtube-shorts-scraper.md
- **Developed by:** [MLG Data](https://apify.com/mlg14) (community)
- **Categories:** Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$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.

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 Scraper

Scrape public YouTube Shorts from one or more channels, including publication dates, views, likes, comments, duration, captions, and channel profile details. Export YouTube Shorts data to JSON, CSV, or Excel for recurring channel research without assembling separate video and channel records yourself.

Each result is one Short. The actor starts from a channel's Shorts tab, follows additional pages when the channel has them, opens each public Short for exact video details, and attaches the channel's public About information. Field names stay consistent across channels, allowing you to compare uploads, engagement, and publication timing in one dataset.

### What data can you extract from YouTube Shorts?

The table lists every dataset field. Availability varies because creators can hide details, remove videos, disable comments, or publish a Short without captions. A missing value is null, except for lists that naturally have no entries.

| Field | Description | Example |
| --- | --- | --- |
| title | Public Short title | Can We Build an Entire Village? |
| type | Content type | shorts |
| id | Stable video ID | T\_SMf9j50uc |
| url | Direct Shorts page | https://www.youtube.com/shorts/T\_SMf9j50uc |
| thumbnailUrl | Largest thumbnail exposed by the video page | Image URL |
| viewCount | Exact public views when video metadata supplies them | 19683046 |
| date | Publication time in UTC | 2026-09-18T16:00:01Z |
| likes | Public like count when shown | 725084 |
| location | Reserved video location field; this source does not reliably expose it | null |
| channelName | Channel display name | Public channel title |
| channelUrl | Canonical channel link | Channel URL |
| channelId | Stable channel ID | UCX6OQ3DkcsbYNE6H8uQQuVA |
| channelUsername | Handle without the @ sign | Channel handle |
| channelDescription | Public channel description | Channel bio |
| channelJoinedDate | Join date as displayed on About | Feb 19, 2012 |
| channelDescriptionLinks | Public external links found on About | URL list |
| channelLocation | Country on the channel About view | United States |
| channelAvatarUrl | Channel profile image | Image URL |
| channelBannerUrl | Channel banner image | Image URL |
| channelTotalVideos | Public count of all channel videos | 1003 |
| channelTotalViews | Public lifetime channel views | 140927554036 |
| numberOfSubscribers | Rounded subscriber count shown publicly | 518000000 |
| isChannelVerified | Whether the channel header shows a verified badge | true |
| inputChannelUrl | Normalized channel URL used for this request | Channel URL |
| isAgeRestricted | Whether player metadata indicates an age gate | false |
| duration | Short length in hours, minutes, and seconds | 00:00:40 |
| commentsCount | Public comment count; abbreviated values are estimates | 14000 |
| text | Public video description | Empty string when absent |
| subtitles | Caption language codes exposed by the video page | \["en"] |
| order | Zero based order within the returned channel results | 0 |
| commentsTurnedOff | False when a comments panel is present; otherwise unknown | false |
| fromYTUrl | Channel Shorts page used for discovery | Shorts tab URL |
| isMonetized | Monetization state if publicly knowable | null |
| hashtags | Distinct hashtags in title and description | \["#shorts"] |
| isMembersOnly | Membership restriction if publicly knowable | null |
| input | Normalized input channel URL | Channel URL |
| fromChannelListPage | Channel section that yielded the video | shorts |
| captionLanguages | Available caption language codes | \["en"] |
| error | Error code on a channel level error row | CHANNEL\_HAS\_NO\_SHORTS |
| note | Explanation on an error row | No matching public Shorts found |

Channel fields repeat on each Short. This makes a CSV row useful on its own and avoids a second join when comparing channels. The video ID is the best key for deduplication across repeated runs. Counts reflect the public page at collection time and can change later. A channel card may abbreviate views; the actor replaces that label with the exact video count when the Short page supplies one.

The subtitles and captionLanguages fields report availability by language code. They do not contain transcript text. The commentsCount value comes from the public comments header, where large numbers can appear as rounded labels such as 14K. The numberOfSubscribers value is also based on a rounded public display, while channelTotalViews and channelTotalVideos come from About. The actor does not infer monetization or membership status from a missing badge, so those fields are normally null.

### How to scrape YouTube Shorts

1. Enter one or more channel handles or full channel URLs in channels. A plain handle, an @ handle, and a channel URL all work.
2. Set maxResultsShorts to the number of Shorts you want from each channel. Set maxItems when you also need one total cap across every channel.
3. Choose Newest, Popular, or Oldest. Add oldestPostDate when you want a publication cutoff; this uses Newest order so the actor can stop after older uploads.
4. Run the actor. Open the default dataset to inspect the rows, then download JSON, CSV, or Excel.

For recurring monitoring, start with a moderate limit and schedule the same input. Deduplicate later by video ID: a Short can appear in several scheduled results because the newest page shifts as channels publish. To compare channels fairly, choose the same per channel limit and record the run time with your exported dataset. Engagement counts are snapshots, not a historical series provided by the site.

### Input

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| channels | String list | Required | Public handles or YouTube channel URLs. |
| maxResultsShorts | Integer | 25 | Maximum matching Shorts per channel. |
| oldestPostDate | String | None | Earliest UTC publication date, such as 2026-01-01, or a relative age such as 7 days. |
| sortChannelShortsBy | Choice | NEWEST | NEWEST, POPULAR, or OLDEST; a date cutoff forces Newest. |
| maxItems | Integer | 0 | Total result cap across all channels; zero means no additional total cap. |
| proxyConfiguration | Object | Enabled | Proxy settings for public page access. |

A realistic input uses a canonical channel URL. The date filter is optional and should be left out when you want the chosen sort order without a publication cutoff.

```json
{
  "channels": ["https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA"],
  "maxResultsShorts": 50,
  "sortChannelShortsBy": "NEWEST",
  "maxItems": 50
}
```

You can instead provide several handles in the array. The per channel limit applies independently, while maxItems can stop collection in the middle of a later channel. If you set a date, use an absolute YYYY-MM-DD value for a repeatable cutoff. Relative ages are evaluated at run time, which is useful for daily monitoring but changes the date window on each run. Dates are compared against the publication timestamp from the public video page, not the age label on a channel card.

### Output example

This excerpt comes from a successful 35 result run. The example omits the long channel bio and image URLs for readability; those fields were present in the dataset. Counts are a snapshot from that run and will change as viewers interact with the Short.

```json
{
  "title": "Can We Build an Entire Village?",
  "type": "shorts",
  "id": "T_SMf9j50uc",
  "url": "https://www.youtube.com/shorts/T_SMf9j50uc",
  "viewCount": 19683046,
  "date": "2026-09-18T16:00:01Z",
  "likes": 725084,
  "channelId": "UCX6OQ3DkcsbYNE6H8uQQuVA",
  "channelUrl": "https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA",
  "numberOfSubscribers": 518000000,
  "duration": "00:00:40",
  "commentsCount": 14000,
  "subtitles": ["en"],
  "captionLanguages": ["en"],
  "hashtags": [],
  "order": 0
}
```

Normal rows identify a video with id and url. Error rows instead contain input, url, error, and note. An existing channel with no matching public Shorts produces CHANNEL\_HAS\_NO\_SHORTS, while a strict publication cutoff can produce DATE\_FILTER\_TOO\_STRICT. Check error before treating every row as a video in downstream processing. A channel failure does not prevent later channels in the same input from being attempted.

### Use cases

- **Channel benchmarking:** Compare how often channels publish Shorts, which topics appear in titles, and the public views and likes each upload receives. Use the same collection window for channels with different histories.
- **Campaign monitoring:** Track Shorts published after a launch date. Inspect titles, descriptions, and hashtags for relevant mentions, then review the original video for context.
- **Editorial planning:** Build a list of recent formats and running times. Duration, publication time, title, and engagement fields help editors identify patterns worth reviewing manually.
- **Competitive research:** Export comparable records from several public channels. Channel IDs prevent confusion when a handle changes, and video IDs prevent duplicate counting between runs.
- **Caption coverage audits:** Check which public Shorts advertise captions and which language codes appear. The fields indicate availability, allowing a separate transcription process to focus on videos that need it.
- **Historical snapshots:** Schedule collection and store each export with its run date. Later exports can show how engagement changed, provided you keep your own history.

These examples use public video and channel information. Interpret counts in context: a newly posted Short has had less time to accumulate views, and a channel's subscriber count is rounded. A title or hashtag match is a discovery signal, not proof that the video discusses a topic in depth. Review the video when a decision depends on meaning or context.

### How much does it cost to scrape YouTube Shorts?

The configured result price is **$1 per 1,000 dataset rows**, or **$0.001 per row**. Platform usage is included in that result price for users of the actor. The actor also stops when the platform reports that the run's charge limit has been reached. A result limit controls how many rows can be delivered; it does not promise that every requested channel has that many public Shorts.

| Delivered results | Result charge |
| ---: | ---: |
| 35 | $0.035 |
| 250 | $0.25 |
| 1,000 | $1.00 |
| 5,000 | $5.00 |

For example, 50 Shorts from each of five channels produces at most 250 video rows, or $0.25 in result charges. Collecting 1,000 rows across a larger list costs $1.00. A 5,000 row archive costs $5.00 if all rows are delivered. Channel error rows also occupy dataset rows, so inspect errors when comparing delivered rows with collected videos. The account or run may impose a lower charge cap.

The measured 35 result check completed in about 45 seconds, with no residential proxy transfer. This is one observed run, not a fixed speed guarantee. Runtime depends on page response times, video availability, channel size, and whether additional channel pages are needed. The actor opens each public Short for exact details, so a large run makes more requests than a simple list of links.

### Tips for best results

Use a channel URL when a plain handle may be ambiguous. The actor accepts a channel's Shorts URL and normalizes it to the base channel before collecting. A stable channel ID URL is useful when a creator changes a handle. Keep one entry per distinct channel; repeated entries may produce repeated Shorts because each is processed independently.

Choose NEWEST for ongoing monitoring. It follows the channel's latest list and pairs naturally with a date cutoff. POPULAR follows the site's public Popular chip and is better for finding established high view Shorts. OLDEST is useful for exploring a channel's early Shorts. These are the channel's own orderings; the actor does not compute a separate popularity ranking.

Start with 25 to 50 results while checking an unfamiliar channel. Large channels expose additional pages, and the actor follows continuation tokens to move beyond the first page. There is a 100 page safety cap per channel to prevent an endless crawl if the site repeatedly serves the same token. Duplicates within a channel run are removed by video ID before results are delivered.

For a fixed historical cutoff, use a calendar date. A relative age such as 7 days moves with the run. With a cutoff, the actor uses Newest order even if another sort is selected, then stops after encountering older results. If a channel has no matching Shorts, expect an error row rather than an empty dataset with no explanation.

Use maxItems when the combined output of several channels needs a strict ceiling. A per channel limit of 100 across ten channels can produce up to 1,000 Shorts, but maxItems set to 300 stops at 300 rows. Channel order matters with a total cap because later channels may not be reached. Schedule separate runs if every channel must receive the same quota.

### Limits

Only publicly accessible Shorts are collected. Private, removed, unavailable, or sign-in restricted videos may not yield a normal result. The actor records a channel level error when no public Shorts match, but it may skip an individual Short whose public metadata cannot be read. A channel with Shorts visible only to signed-in viewers cannot be fully represented by anonymous access.

The source exposes some numbers as rounded labels. Subscriber totals and abbreviated comment counts are estimates; exact video views and likes come from the video page when available. Comment text, full caption text, video files, and viewer identities are outside this dataset. Subtitles lists language codes and does not assert that a complete transcript is available for download.

Channel About details depend on that view being public and reachable. If it fails, the actor can still return a Short and fields from the main channel page, while About-specific totals, country, and join date may be null. Location, isMonetized, and isMembersOnly are usually unknown because the public pages used here do not reliably establish them. Unknown is intentionally distinct from false.

The site can change its page data or continuation format. A change may cause fewer results, missing fields, or an error row until the actor is updated. The 100 page cap also limits extraordinarily large channel archives. Date filtering assumes the channel's Newest list is in publication order; if the site mixes older items into that list, a strict cutoff may end collection before every possible match is found.

### Use with MCP

The input schema gives automation clients clear parameter names and descriptions. A client can run the actor, read the dataset, and pass returned video URLs into a review workflow. Two example requests are:

> Collect the latest 40 public Shorts from this channel URL and return the five with the highest view counts, including publication date and duration.

> Check Shorts published in the last 7 days for these three channels. Return video IDs, titles, public engagement counts, and caption language availability.

Use the returned id or url as a durable reference in a follow-up task. Treat counts as values measured when the run completed. If a summary depends on a video's spoken content, obtain and review that content separately; the output here provides metadata and caption availability rather than a transcript.

### FAQ

#### Is it legal to collect YouTube Shorts data?

The actor reads public pages. Follow the site's terms and applicable law, including privacy and copyright rules, for your own use. Avoid using channel or video data to profile private individuals or make unsupported claims about a creator. This dataset does not collect private contact information or viewer identities.

#### Do I need to configure a proxy?

The default input uses the platform proxy. The successful 35 result run used no residential transfer. Leave the setting at its default unless a particular environment requires a different configuration. If a public page becomes unavailable, reducing request volume or trying again later may help.

#### How fast is a run?

One measured 35 result run took about 45 seconds. The actor requests a channel page, its About view, public Short pages, and continuation pages where required. Network conditions, the number of Shorts, and site responses determine actual duration. Use the measured run as a rough reference, not a throughput guarantee.

#### Can I schedule and monitor collection?

Yes. Schedule the actor with the same input and inspect each run's status and default dataset. For monitoring, use a recent date cutoff and deduplicate by video ID in your own storage. A successful run can still include error rows for specific channels, so check error before counting videos.

#### Can I export to a spreadsheet?

Yes. Download the default dataset as CSV or Excel, or request JSON for a database pipeline. Each video row repeats channel details to make sorting and filtering straightforward. Long channel descriptions can make spreadsheet cells bulky; hide that column if analysis focuses on engagement.

#### Why is a field empty?

The site may not publish it, a creator may have disabled a feature, or the page may not expose it to anonymous viewers. Captions can be absent, comments can be hidden, and some profile details exist only on About. Null means the actor did not establish the value; it should not be read as zero or false.

#### Why are comment and subscriber counts rounded?

Those values can be displayed with compact labels. The actor converts the public label to a numeric estimate, such as 14K to 14000. Exact views and likes are taken from video metadata when available. Keep the precision difference in mind when ranking videos by small changes.

### Integrations

Run the actor through the platform API, schedule it, or trigger downstream work with a webhook. The default dataset can feed an automation service, spreadsheet, or data warehouse. Use video ID for updates and keep the run timestamp with each snapshot so reports can distinguish publication time from collection time.

### Support

Open an issue on the Issues tab; we reply within 24h and add fields on request.

# Actor input Schema

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

Channel handles or YouTube channel URLs. One output row is produced per public Short.

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

Maximum Shorts to collect from each channel, after the date filter.

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

Include Shorts published on or after this UTC date (YYYY-MM-DD), or use a relative age such as 7 days. Date filtering uses newest sorting.

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

Choose the channel's Latest, Popular, or Oldest order. A date filter always uses Latest.

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

Stop after this many rows across all channels. Set 0 for no total cap.

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

Apify Proxy is used automatically; change only if needed.

## Actor input object example

```json
{
  "channels": [
    "NASA",
    "https://www.youtube.com/@MrBeast"
  ],
  "maxResultsShorts": 35,
  "oldestPostDate": "2026-01-01",
  "sortChannelShortsBy": "NEWEST",
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `shorts` (type: `string`):

Public Shorts and channel details in the default dataset.

# 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": [
        "MrBeast"
    ],
    "maxResultsShorts": 35
};

// Run the Actor and wait for it to finish
const run = await client.actor("mlg14/youtube-shorts-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 = {
    "channels": ["MrBeast"],
    "maxResultsShorts": 35,
}

# Run the Actor and wait for it to finish
run = client.actor("mlg14/youtube-shorts-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 '{
  "channels": [
    "MrBeast"
  ],
  "maxResultsShorts": 35
}' |
apify call mlg14/youtube-shorts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mlg14/youtube-shorts-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/7dyS3XQhyWqXS7anv/builds/blkw5qDSyCZzt6arm/openapi.json
