14

I want a way to get YouTube shorts for a specific channel from YouTube API. I looked every where and I couldn't find anything.

Currently I can get a playlist ID for all channel videos with this endpoint:

request = youtube.channels().list(
    part="contentDetails",
    id=id
)

I also tried these parameters:

request = youtube.channels().list(
    part="snippet,contentDetails,statistics,brandingSettings",
    id=id
)

So is there a way to get YouTube shorts from a specific channel from YouTube API or any other source if it's available.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Computer Mind
  • 411
  • 2
  • 5
  • 12
  • Note that [I modified significantly my answer](https://stackoverflow.com/posts/71194751/revisions), providing [at least a 48 times better complexity](https://github.com/Benjamin-Loison/YouTube-operational-API/commit/786616ff37a4eeec1f06fbff4d248b98cbd8f839#diff-651cb6f72df27343556303c689f24c67c4cb90e2881f464e665c151429551dacR133-R134). – Benjamin Loison Oct 31 '22 at 17:11

7 Answers7

21

One way of detecting if a YouTube video ID is a Short without even using the API is to try a HEAD HTTP request to the /shorts/ version of the URL and see if it redirects you.

https://www.youtube.com/shorts/hKwrn5-7FjQ is a Short and if you visit that URL, you'll get an HTTP status code of 200 and the URL won't change.

https://www.youtube.com/watch?v=B-s71n0dHUk is not a Short, and if you visit https://www.youtube.com/shorts/B-s71n0dHUk, you get a 303 redirect back to the original URL.

Keep in mind, that this behavior might change down the line, but it works as of May 2022.

Joost Schuur
  • 4,417
  • 2
  • 24
  • 39
  • This is correct, requires no 3rd party solution :) – Ian Steffy May 12 '22 at 12:01
  • What happens when someone imports the short as `https://www.youtube.com/watch?v=pKML4pZozDY` – Ian Steffy May 12 '22 at 12:24
  • 2
    @IanSteffy Extract the video ID from the URL first and then check the shorts URL variant. In my current project, I don't store the URL, I just store each video ID in the database anyway. – Joost Schuur May 14 '22 at 07:17
  • @JoostSchuur Is there a way I can programmatically make a request? I tried `fetch` but CORS comes in between – Usman Sabuwala Nov 14 '22 at 08:13
  • 1
    BTW, I added a feature request for this a while back. If others want to chime in: https://issuetracker.google.com/issues/232112727. A Google dev says they 'added this to the feature request list' as of May 2022. – Joost Schuur Nov 29 '22 at 20:54
  • @UsmanSabuwala CORS hasn't been an issue for me. I just run `res = await fetch(shortsUrl, { method: 'head' })` and check `res?.url?.startsWith(shortsUrl)` – Joost Schuur Dec 04 '22 at 15:22
  • Doesn't seem like it works as of Feb 2023, even with "follow redirects off", it shows 200 now – divay pandey Feb 27 '23 at 06:52
  • @divaypandey The project where I implemented this in still detects Shorts and `curl -I https://www.youtube.com/shorts/B-s71n0dHUk` still shows a 303 redirect for me right now, suggesting this still works. – Joost Schuur Mar 05 '23 at 13:04
  • In Europe this doesn't seem to work. It always returns a 200 regardless because when called programatically the response is a cookie acceptance page. Not sure if I can get around this? – mbrookson May 24 '23 at 13:06
  • @mbrookson Not sure why this would be region specific. If you visit https://www.youtube.com/shorts/B-s71n0dHUk in a browser, do you not get redirected to https://www.youtube.com/watch?v=B-s71n0dHUk ? I'm in the UK (which not everyone considers Europe, but I still do!) and everything still works as I described in my answer here. – Joost Schuur Jun 23 '23 at 14:55
  • @JoostSchuur I'm also in the UK but have tried this through a VPN through Germany. In the UK or EU you will be shown a cookie modal due to GDPR rules. You won't see it if you've already accepted the cookie policy in your browser, but try it in an incognito window and you should see the same result. – mbrookson Jun 24 '23 at 07:30
  • @mbrookson I can't quite replicate that. Even in incognito mode, when VPN'd to Germany, if i visit a shorts URL (https://youtube.com/shorts/B-s71n0dHUk), I get redirected and see no cookie notice. But you really just need to make a HEAD HTTP request (try `curl -I https://youtube.com/shorts/B-s71n0dHUk`) and look at the response type (200 vs 303) to programmatically know if a URL is a short or not. – Joost Schuur Jun 29 '23 at 09:40
10

It seems that once again YouTube Data API v3 doesn't provide a basic feature.

For checking if a given video is a short:

I would recommend you to use my open-source YouTube operational API. Indeed by requesting the JSON document https://yt.lemnoslife.com/videos?part=short&id=VIDEO_ID containing item["short"]["available"] boolean, your problem is solved.

Example of short id: ydPkyvWtmg4

For listing shorts of a channel:

I would recommend you to use my open-source YouTube operational API. Indeed by requesting the JSON document https://yt.lemnoslife.com/channels?part=shorts&id=CHANNEL_ID. The entry item["shorts"] contains the data you are looking for. Note that the pagination works as the one of YouTube Data API v3.

Example of result for channel UC5O114-PQNYkurlTg6hekZw:

{
    "kind": "youtube#channelListResponse",
    "etag": "NotImplemented",
    "items": [
        {
            "kind": "youtube#channel",
            "etag": "NotImplemented",
            "id": "UC5O114-PQNYkurlTg6hekZw",
            "shorts": [
                {
                    "videoId": "fP8nKVauFwc",
                    "title": "India: United Nations Counter Terrorism Committee Watch LIVE #shorts",
                    "thumbnails": [
                        {
                            "url": "https:\/\/i.ytimg.com\/vi\/fP8nKVauFwc\/hq720_2.jpg?sqp=-oaymwEYCNAFENAFSFryq4qpAwoIARUAAIhC0AEB&rs=AOn4CLCgJEYgv_msT5pkfWeEEN3VBt4wjg",
                            "width": 720,
                            "height": 720
                        }
                    ],
                    "viewCount": 3700
                },
                ...
            ],
            "nextPageToken": "4qmFsgLlARIYVUM1TzExNC1QUU5Za3VybFRnNmhla1p3GsgBOGdhU0FScVBBVktNQVFxSEFRcGZRME00VVVGU2IyWnZaMWxqUTJob1ZsRjZWbEJOVkVVd1RGWkNVbFJzYkhKa1dFcHpWa2RqTW1GSFZuSlhibU5SUVZOSlVrTm5PSGhQYWtVeVRtcGplVTE2VlRST2FrVXdUbXBCY1VSUmIweFhWRUl5VGtab1dGSllSbGRNVmtVU0pEWXpOakJoTkRVNUxUQXdNREF0TWpKaE15MDRObUV6TFdRMFpqVTBOMlZqWVRSbFl4Z0I=,CgtuNjFmZlJlR0QxcyiVgICbBg=="
        }
    ]
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
  • Thank you for answering Benjamin. I tried filtering by tag as you mention in your answer but the issue is when i give normal video ID i get list of tags and every think is ok, but when i give a short video ID i get empty list with no values. The question is "how do i know the video is short if there is no tags to filter? – Computer Mind Mar 10 '22 at 12:08
  • I wrote a simple code that gets uploads playlist ID from a channel that am certain it has shorts, and then i wrote a function to handles pagination to get a list contains all channel video IDs. And finally i wrote a function to get list of tags for each video ID, the issue is none of them has a tag named 'short' or 'shorts' – Computer Mind Mar 10 '22 at 12:46
  • Indeed my bad, I'm not accustomed to watch/work with YouTube shorts, I updated my answer :) – Benjamin Loison Mar 10 '22 at 22:55
5

You can use the new dimension called 'creatorContentType' from Youtube Analytics and Reports API.

    // You can get IDs from PlaylistItems or Search API
    const IDs = ["videoID1", "videoID2", "videoID3"];

    // Get the analytics data of selected videos based on their IDs
    const { data: analyticsData } = await youtubeAnalytics.reports.query({
      ids: "channel==MINE",
      startDate: "2019-01-01",
      // Today's date
      endDate: new Date().toISOString().split("T")[0],
      metrics: "views",
      dimensions: "video,creatorContentType",
      filters: `video==${IDs.join(",")}`,
      access_token,
    });

It basically returns values listed below:

Value Description
LIVE_STREAM The viewed content was a YouTube live stream.
SHORTS The viewed content was a YouTube Short.
STORY The viewed content was a YouTube Story.
VIDEO_ON_DEMAND The viewed content was a YouTube video that does not fall under one of the other dimension values.
UNSPECIFIED The content type of the viewed content is unknown.

Notes:

  1. Don't forget it returns values just for the videos uploaded after 01.01.2019.
  2. Don't forget to add analytics scopes and enable Analytics and Reports API.
1

Below is a sample python code to send the HEAD HTTP request.

import requests

def is_short(vid):
    url = 'https://www.youtube.com/shorts/' + vid
    ret = requests.head(url)
    # whether 303 or other values, it's not short
    return ret.status_code == 200
wholehope
  • 41
  • 4
1

Looking at the playlist IDs that can be retrieved from the API's contentDetails.relatedPlaylists.uploads, we can see that the "UC" at the beginning of the channel ID is replaced with "UU".

The same format can be used by replacing "UC" at the beginning of the channel ID with "UUSH" to get a playlist of only short videos.

For example, a channel ID of "UCutJqz56653xV2wwSvut_hQ" will result in a playlist ID of "UUSHutJqz56653xV2wwSvut_hQ".

Also, other prefixes exist:

prefix contents
UULF Videos
UULP Popular videos
UULV Live streams
UUMF Members-only videos
UUMO Members-only contents (videos, short videos and live streams)
UUMS Members-only short videos
UUMV Members-only live streams
UUPS Popular short videos
UUPV Popular live streams
UUSH Short videos

However, this pattern was found by me by acquiring all playlists from "UUAA" to "UUZZ" and is not officially announced by YouTube.

coco0419
  • 11
  • 1
0

I don't know why but I don't get status code 303 whether it's a short or not with axios. So this is another way of checking if it's a short or not.

const isShort = async (videoId) => {
    const url = "https://www.youtube.com/shorts/" + videoId
    const res = await axios.head(url)
    console.log(res.request.res.responseUrl)
    // if it's a short it ends with "/shorts/videoId"
    // if it's NOT a short it ends "/watch?=videoId"
}

Maybe axios automatically redirects?

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
suzu
  • 1
  • It looks like it depends on the environment. You can check the bug report for more information: https://github.com/axios/axios/issues/3924 In short, XmlHttpRequests do automatically redirects, used in Node you can configure the behavior with "maxRedirects". – Norbert Mar 08 '23 at 15:35
0

To get short videos of a specific channel using YouTube data API you can use the below javascript snippet:

You can set the 'type' parameter to 'short' to get the short videos specifically or video to get all videos.

export const getShortVideos = async channelId => {
  try {
    const response = await axios.get(`${BASE_URL}/search`, {
      params: {
        part: 'id',
        channelId: channelId,
        maxResults: 50, // You can adjust this number as needed
        type: 'short',
        key: YOUTUBE_API_KEY,
        order: 'date',
      },
    });

    const videos = response.data.items.map(item => {
      return item.id.videoId;
    });

    return videos;
  } catch (error) {
    console.error('Error fetching data:', JSON.stringify(error, null, 2));
    return [];
  }
};

This will return the IDs of the short videos, You can then use those IDs to get specific information for a short video or make a link from the ID to show it on your app or web page. For example:

https://www.youtube.com/shorts/${videoId}

Ibrahim
  • 59
  • 4