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

- **URL**: https://apify.com/s-r/youtube-shorts-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Social media, Marketing
- **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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

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

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## YouTube Shorts Scraper: Channel Shorts with Views in JSON

A hosted **youtube shorts scraper** that pulls every Short from any YouTube channel as structured JSON, view counts, like counts, publish dates, durations, and thumbnails included. Point it at channel URLs, @handles, or UC channel IDs and it returns the Shorts through YouTube's own InnerTube web API, so there's no API key, no quota, and no Chrome to run yourself.

### What you get

- **One clean row per Short**: video ID, `/shorts/` URL, title, description, channel name, channel ID, channel URL, and channel subscriber count.
- **Engagement metrics**: view count (both the raw integer and the localized "1.2M views" text), like count, and comment count when `fetch_details` is on.
- **Publish date and duration**: exact publish date and `duration_seconds` for every Short, so you can sort by recency or filter by length.
- **Up to 1,000 Shorts per channel**: paginated through YouTube's continuation tokens, so long back-catalogues come through in a single run.
- **No YouTube Data API quota**: the Actor uses the same internal web API the YouTube client calls, so you never touch your 10,000 daily quota units.
- **Country and language control**: set the storefront `country` and `language` to get view counts and dates formatted for the market you care about.
- **Timing metadata**: every row carries `fetched_in_seconds` and the `input` that produced it, so runs are auditable.

### Why scrape YouTube Shorts

YouTube Shorts has no official public API. The YouTube Data API v3 exposes regular videos, but it has no dedicated Shorts endpoint, no reliable Shorts flag, and it silently mixes Shorts in with long-form uploads. If you want a clean list of just the Shorts a channel has posted, the official API leaves you guessing. This Actor reads the channel's Shorts tab directly, the same feed a viewer sees, so what you get back is exactly the Shorts, nothing else.

The engagement data is the second problem. View counts, like counts, and publish timing for Shorts live inside the mobile-first Shorts player, and they're formatted for display ("1.2M views", "3 days ago") rather than served as clean numbers. Pulling that at scale by hand means scrolling an endless vertical feed and reading labels off the screen. This Actor does it server-side and hands you both the abbreviated text and, where available, the exact numeric values, so you can chart trends instead of screenshotting them.

The third reason is quota and maintenance. Anyone who has tried a **youtube shorts downloader** browser extension or a homegrown Python scraper knows the drill, they break every time YouTube ships a UI change, and the Data API route caps you at 10,000 units a day. This Actor runs against the InnerTube API on hosted infrastructure that's patched as YouTube evolves, and it bills per Short instead of per month.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `channels` | array | **required** | One or more channel identifiers, full URLs (`youtube.com/@handle`, `youtube.com/channel/UC…`), bare `@handles`, or `UC…` channel IDs. |
| `max_results` | integer | `100` | Shorts to collect per channel (1–1,000). Newest first. |
| `fetch_details` | boolean | `false` | When true, makes an extra request per Short to add `like_count`, `comment_count`, the exact `published_date`, and `duration_seconds`. |
| `country` | string | `US` | Storefront country code, affects how view counts and dates are localized. |
| `language` | string | `en` | Interface language for titles, descriptions, and date text. |

### Output

Every run pushes results to the Apify dataset as JSON, one record per Short:

```json
{
  "video_id": "abc123XYZ",
  "url": "https://www.youtube.com/shorts/abc123XYZ",
  "title": "How we hit 1M subs in 90 days",
  "description": "The full breakdown of our short-form strategy.",
  "channel_name": "Creator Studio",
  "channel_id": "UCBR8-60-B28hp2BmDPdntcQ",
  "channel_url": "https://www.youtube.com/channel/UCBR8-60-B28hp2BmDPdntcQ",
  "channel_subscribers": "1.4M",
  "published_date": "2026-06-28",
  "view_count": 2380194,
  "view_count_text": "2.3M views",
  "like_count": 84200,
  "comment_count": 1130,
  "duration_seconds": 47,
  "thumbnail_url": "https://i.ytimg.com/vi/abc123XYZ/oardefault.jpg",
  "input": "https://www.youtube.com/@creatorstudio",
  "fetched_in_seconds": 2.9
}
````

Notes on the fields:

- `view_count` is the numeric value, `view_count_text` is the raw label YouTube shows ("2.3M views"), kept unchanged so you can verify it against the page.
- `like_count`, `comment_count`, exact `published_date`, and `duration_seconds` are populated when `fetch_details` is true. With details off, they may be absent or approximate.
- `channel_subscribers` comes through in YouTube's abbreviated form ("1.4M"), trivial to parse downstream if you need an integer.

You can download the dataset as JSON, JSONL, CSV, or Excel from the Apify console, stream it via the Apify API, or pipe it to webhooks, S3, BigQuery, and Apify's other integrations.

### Use cases

**Short-form content strategists** use it to reverse-engineer what works on a channel. Pull a competitor's last 300 Shorts, sort by `view_count`, and the outliers tell you which hooks, topics, and durations actually broke out. Because `duration_seconds` and `published_date` come through per Short, you can correlate length and posting cadence against views instead of guessing.

**Trend researchers** scrape a basket of channels in one niche to spot format shifts early. When the same visual gimmick starts showing up across ten creators inside a week, the publish dates make the wave visible before it hits mainstream. Running the same channel list on a schedule turns that into a rolling trend tracker.

**Influencer analysts** vet creators before a sponsorship. Real reach shows up in the spread between `view_count` and `channel_subscribers`, and authentic engagement shows up in the `like_count` and `comment_count` ratios. A channel whose Shorts pull views far below its subscriber count, or whose likes don't track its views, tells you fast where the audience is soft.

**Brand monitors** watch for their product showing up in creator Shorts. Point the Actor at the channels that cover your category, then filter titles and descriptions for mentions. The comment and like counts tell you which of those mentions actually landed, so you can prioritize outreach to the creators whose Shorts about you are performing.

### How it compares

| | This Actor | streamers/youtube-shorts-scraper |
|---|---|---|
| Price per 1,000 Shorts | **$3.20** | $4.00 |
| Date filter / publish date | **Bundled in base event** | Separate add-on, +$0.0013 per Short |
| Likes, comment count, duration | **Bundled in base event** | Charged as extras |
| Pricing model | Pay-per-event | Pay-per-event |
| API key or quota | None (InnerTube) | None (InnerTube) |

We undercut streamers by 20% on the base rate ($3.20 versus $4.00 per 1,000 Shorts). They also meter a separate $0.0013-per-Short charge for date filtering, we fold likes, comment count, publish date, and duration into the single per-Short event, so there's no surprise line item.

### Pricing

Pay-per-event. You pay **$0.0032 per Short** returned ($3.20 per 1,000 Shorts), plus a **$0.002 actor-start fee** each time a run begins. No monthly subscription, no minimum. A run that pulls 500 Shorts costs about $1.60 in event fees plus the fractional start fee. Enabling `fetch_details` doesn't change the per-Short price, it adds requests behind the scenes but bills at the same rate.

### Limits and gotchas

- **Channel input only.** The Actor scrapes the Shorts feed of a channel. It does not take a single `/shorts/` URL as input, if you already have specific Short IDs, this isn't the tool for looking them up one by one.
- **`fetch_details` adds requests per Short.** With it on, each Short triggers an extra fetch for likes, comments, exact date, and duration. Runs take longer on large `max_results`, though the per-Short price is unchanged.
- **Free-tier runs are capped at 10 Shorts.** Apify free-plan users get up to 10 results per run so they can test the output shape. Paid Apify users run to the full `max_results`.
- **Abbreviated numbers where YouTube abbreviates.** `channel_subscribers` and `view_count_text` come through in YouTube's short form ("1.4M"). `view_count` itself is numeric.
- **Newest first, and that's the only order.** Shorts return in reverse-chronological order. There's no server-side sort by views or engagement, sort the dataset downstream.
- **Localized output follows `country` and `language`.** View-count text and dates are formatted for the market you set. Change them and the display strings change with them.
- **Private, deleted, or members-only Shorts are skipped.** Only publicly visible Shorts on the channel's Shorts tab come through.

### FAQ

#### How do I scrape YouTube Shorts from a channel?

Paste the channel's URL, @handle, or UC ID into the `channels` field, set `max_results` to how many Shorts you want (up to 1,000), and run. The Actor reads the channel's Shorts tab and returns one JSON row per Short. You can pass several channels at once and it processes them in sequence.

#### Can I get Shorts view and like counts?

Yes. Every Short comes back with `view_count` (numeric) and `view_count_text` (the "2.3M views" label). Turn on `fetch_details` to also get `like_count` and `comment_count`, along with the exact publish date and `duration_seconds` for each Short.

#### Do I need a YouTube API key or quota?

No. The Actor calls YouTube's internal InnerTube web API, the same one the YouTube site uses, so there's no API key to obtain and none of your YouTube Data API quota gets consumed.

#### How many Shorts can I pull per channel?

Up to 1,000 per channel per run, set via `max_results`. They come back newest first. Free-tier Apify accounts are capped at 10 results per run for testing, paid accounts get the full count.

#### Why are some engagement fields empty unless I enable fetch\_details?

Likes, comment count, exact publish date, and duration aren't in the lightweight Shorts feed, they need an extra request per Short. To keep default runs fast and cheap the Actor fetches them only when `fetch_details` is true. View counts and titles are always included either way.

#### Can I run this on a schedule to track a channel over time?

Yes. Apify has built-in scheduling. Point it at your channel list on a daily or weekly cadence and diff each run against the last to watch view counts climb and catch new Shorts as they post.

### Related Actors

- [Youtube Scraper](https://apify.com/s-r/youtube-scraper) - Scrape YouTube videos by search term, channel, or video URL.
- [Youtube Comments](https://apify.com/s-r/youtube-comments) - Scrape all comments from any YouTube video.
- [Free Youtube Transcript](https://apify.com/s-r/free-youtube-transcript) - Get the full transcript of any YouTube video.

# Actor input Schema

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

YouTube channel URLs, @handles, or channel IDs (UC…). One per line.

## `max_results` (type: `integer`):

Maximum Shorts to collect per channel (1–1000).

## `fetch_details` (type: `boolean`):

Enrich every Short with like count, comment count, exact publish date, duration, full description and category (extra requests per Short).

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

Two-letter country code (gl).

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

Two-letter interface language code (hl).

## Actor input object example

```json
{
  "channels": [
    "@mkbhd"
  ],
  "max_results": 20,
  "fetch_details": true,
  "country": "US",
  "language": "en"
}
```

# 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": [
        "@mkbhd"
    ],
    "max_results": 20,
    "country": "US",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/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": ["@mkbhd"],
    "max_results": 20,
    "country": "US",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/youtube-shorts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "@mkbhd"
  ],
  "max_results": 20,
  "country": "US",
  "language": "en"
}' |
apify call s-r/youtube-shorts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=s-r/youtube-shorts-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "YouTube Shorts Scraper",
        "description": "",
        "version": "0.1",
        "x-build-id": "cmfKT8ZHCxGWOVcLA"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/s-r~youtube-shorts-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-s-r-youtube-shorts-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/s-r~youtube-shorts-scraper/runs": {
            "post": {
                "operationId": "runs-sync-s-r-youtube-shorts-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/s-r~youtube-shorts-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-s-r-youtube-shorts-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "channels"
                ],
                "properties": {
                    "channels": {
                        "title": "Channels",
                        "type": "array",
                        "description": "YouTube channel URLs, @handles, or channel IDs (UC…). One per line.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "max_results": {
                        "title": "Max Shorts per channel",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum Shorts to collect per channel (1–1000).",
                        "default": 20
                    },
                    "fetch_details": {
                        "title": "Fetch full details",
                        "type": "boolean",
                        "description": "Enrich every Short with like count, comment count, exact publish date, duration, full description and category (extra requests per Short).",
                        "default": true
                    },
                    "country": {
                        "title": "Country",
                        "type": "string",
                        "description": "Two-letter country code (gl).",
                        "default": "US"
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "Two-letter interface language code (hl).",
                        "default": "en"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
