YouTube Shorts API
Read a channel's Shorts tab, newest, most popular or oldest, or fetch individual Short links, and get one structured row per Short with views, likes, comment count, publish timestamp, duration, hashtags, description and thumbnail, plus the channel's subscribers, total views, joined date, country, About links and verified badge. 42 fields per row in the column names the common Shorts scrapers use, so it drops into an existing pipeline. Pay per Short returned, with no browser, no API quota and no login.
Input parameters
| PARAMETER | TYPE | REQ | DEFAULT | DESCRIPTION |
|---|---|---|---|---|
| channels | string[] | no | [nasa] | Channel handles with or without the @ sign, channel URLs in any form, or bare channel ids. Up to 20 channels per run, each returning up to maxResultsShorts Shorts in the chosen order. Give this or startUrls, or both. |
| startUrls | {url}[] | no | — | Direct Short, watch or youtu.be links, up to 200 per run. Combine freely with channels. The date filter does not apply to direct links. |
| maxResultsShorts | integer | no | 10 | Shorts per channel, 1 to 500. A run stops at 1,000 Shorts in total. — drives your bill |
| sortChannelShortsBy | enum | no | NEWEST | NEWEST · POPULAR · OLDEST, the three sort buttons on the channel's Shorts tab. Forced to NEWEST when oldestPostDate is set. |
| oldestPostDate | string | no | — | Only Shorts published on or after this date. An absolute date like 2025-06-03 or a relative span like 7 days, 2 weeks or 3 months. Forces NEWEST order so the listing stops at the first older Short, and adds a small date-filter event per returned Short. — drives your bill |
Output schema
| FIELD | TYPE | DESCRIPTION | NULLABLE |
|---|---|---|---|
| id | string | YouTube video id of the Short. | no |
| url | string | Canonical Short URL. | no |
| title | string | Title of the Short. | no |
| type | string | Content type, always shorts for a Short row. | no |
| text | string | Full description text of the Short. | yes |
| date | string | Publish timestamp in ISO 8601 UTC. Day precision only in the rare case YouTube withholds the exact time. | no |
| duration | string | Length as HH:MM:SS. | yes |
| viewCount | integer | Exact view count at fetch time. | no |
| likes | integer | Exact like count at fetch time. Null when the creator hides likes. | yes |
| commentsCount | integer | Comment count. Exact below 1,000, otherwise parsed from YouTube's rounded figure. Null when comments are turned off. | yes |
| commentsTurnedOff | boolean | True when the creator disabled comments on the Short. | yes |
| hashtags | string[] | Hashtags found in the title and description, with the # sign. | yes |
| descriptionLinks | object[] | URLs found in the description as {url, text} objects. | yes |
| thumbnailUrl | string | Largest available thumbnail image. | yes |
| isAgeRestricted | boolean | Whether YouTube marks the Short as age-restricted. | yes |
| isMembersOnly | boolean | True when the Short is restricted to channel members. | yes |
| location | string | Location attached to the Short when the creator set one; usually null. | yes |
| collaborators | object[] | Collaborating channels on the Short; empty when none. | yes |
| channelName | string | Display name of the channel that published the Short. | no |
| channelUsername | string | Channel handle without the @ sign. | yes |
| channelId | string | YouTube channel id (UC...). | no |
| channelUrl | string | Canonical channel URL in channel id form. | no |
| channelDescription | string | The channel's About text. | yes |
| channelJoinedDate | string | Date the channel was created, as YouTube shows it. | yes |
| channelLocation | string | Country the channel lists in its About section. | yes |
| channelDescriptionLinks | object[] | Links from the channel's About section as {text, url} objects. | yes |
| channelAvatarUrl | string | Channel profile image URL. | yes |
| channelBannerUrl | string | Channel banner image URL. | yes |
| channelTotalVideos | integer | Total videos on the channel. | yes |
| channelTotalViews | integer | Total views across the channel. | yes |
| numberOfSubscribers | integer | Subscriber count. Exact below 1,000, otherwise parsed from YouTube's rounded figure (15.1M = 15100000). | yes |
| isChannelVerified | boolean | Whether the channel shows the verified badge. | yes |
| aboutChannelInfo | object | All channel fields repeated in one object for convenience. | yes |
| order | integer | Zero-based position of the Short in the returned list for its channel. | no |
| input | string | The exact input value (channel or link) that produced this row. | no |
| inputChannelUrl | string | Normalized URL of the channel that was requested. | yes |
| fromYTUrl | string | The YouTube page the Short was read from: the channel's Shorts tab, or the Short link itself for direct links. | no |
| fromChannelListPage | string | shorts when the row came from a channel's Shorts tab; null for direct links. | yes |
| translatedTitle | string | Reserved for a translated title; null in this version. | yes |
| translatedText | string | Reserved for a translated description; null in this version. | yes |
| subtitles | object[] | Reserved; null in this version. Use the YouTube Transcripts API for captions. | yes |
| isMonetized | boolean | Reserved; YouTube does not expose monetization publicly, so this is null. | yes |
Worked examples
{ "channels": ["nasa"], "maxResultsShorts": 25 }
{
"channels": ["MrBeast", "https://www.youtube.com/@nasa"],
"maxResultsShorts": 50,
"sortChannelShortsBy": "POPULAR"
}
{ "channels": ["@nasa"], "maxResultsShorts": 200, "oldestPostDate": "14 days" }
{
"startUrls": [
{ "url": "https://www.youtube.com/shorts/gnuiMgTzKMQ" },
{ "url": "https://youtu.be/CEJXqm2eiJ0" }
]
}
Coverage
Code
curl
curl -X POST "https://api.apify.com/v2/acts/johnvc~youtube-shorts-api/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"channels":["nasa"],"maxResultsShorts":10}'
Python
from apify_client import ApifyClient
client = ApifyClient("APIFY_TOKEN")
run = client.actor("johnvc/youtube-shorts-api").call(
run_input={
"channels": ["nasa", "MrBeast"],
"maxResultsShorts": 25,
"sortChannelShortsBy": "POPULAR",
}
)
for short in client.dataset(run.default_dataset_id).iterate_items():
print(short.get("viewCount"), short.get("likes"), short.get("title"))
MCP
claude mcp add --transport http youtube-shorts \ "https://mcp.apify.com/?tools=actors,docs,johnvc/youtube-shorts-api"
What people use it for
- Tracking a competitor channel's Shorts output, views and posting cadence
- Hashtag and title research across a set of Shorts channels
- Finding creators by subscriber count and engagement, with their About links
- Brand monitoring across channels that talk about your product
- Shorts metadata at scale for moderation and research datasets
- Asking an AI agent for a channel's most viewed Shorts over MCP
More sources for Competitor and market monitoring, Lead sourcing and CRM enrichment, Reviews and reputation monitoring, Transcripts, images and content pipelines, Grounding AI agents and MCP tools →
Alternatives
Use it from an MCP client
Add the Apify MCP server to any MCP client and this API becomes a tool the assistant can call. The server URL is https://mcp.apify.com/?tools=actors,docs,johnvc/youtube-shorts-api. It works with Claude Code (free trial), Claude Cowork (free trial), Cursor and ChatGPT. Then ask in plain language: “Get the 20 most popular Shorts from @nasa with views and likes” or “Which of these three channels posted Shorts this week?”