how do I get youtube shorts from youtube api data v3
Asked Answered
G

9

25

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.

Greenlet answered 20/2, 2022 at 8:30 Comment(2)
Note that I modified significantly my answer, providing at least a 48 times better complexity.Maclaine
I've added an alternative as well - if someone is interested.Benzoin
C
23

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.

Crawler answered 11/5, 2022 at 8:17 Comment(16)
This is correct, requires no 3rd party solution :)Typewriting
What happens when someone imports the short as https://www.youtube.com/watch?v=pKML4pZozDYTypewriting
@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.Crawler
@JoostSchuur Is there a way I can programmatically make a request? I tried fetch but CORS comes in betweenJuline
BTW, I added a feature request for this a while back. If others want to chime in: issuetracker.google.com/issues/232112727. A Google dev says they 'added this to the feature request list' as of May 2022.Crawler
@UsmanSabuwala CORS hasn't been an issue for me. I just run res = await fetch(shortsUrl, { method: 'head' }) and check res?.url?.startsWith(shortsUrl)Crawler
Doesn't seem like it works as of Feb 2023, even with "follow redirects off", it shows 200 nowWreckage
@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.Crawler
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?Ommatidium
@Ommatidium Not sure why this would be region specific. If you visit youtube.com/shorts/B-s71n0dHUk in a browser, do you not get redirected to 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.Crawler
@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.Ommatidium
@Ommatidium I can't quite replicate that. Even in incognito mode, when VPN'd to Germany, if i visit a shorts URL (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.Crawler
hahah, sorry you will hit captchaPhotoactive
@DylanB You won't hit a captcha doing a HEAD HTTP request and looking at the status code. That doesn't return any HTML that could contain a captcha. It only returns HTTP headers. I use this method in production at scale to identify Shorts and haven't had any problems with it.Crawler
Started to get 204s from this endpoint (on the couple I looked at, it was for longs, not shorts). Not sure if this is just an alternate response or a rate limit.Carping
This happens for both longs and shorts, seems to be a form of rate limit.Carping
S
25

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.

This is a demo code using TypeScript to get the prefix. (Demo code)

Soho answered 3/7, 2023 at 7:55 Comment(6)
incredibly helpful. Can you give an example of what the URL would be to retrieve popular short videos (e.g. UUPS?)Narrow
This was extremely helpful to me! Thanks @Soho ! Great answer. For Parseltongue, here's an example call youtube.googleapis.com/youtube/v3/… Just replace the dashes with the rest of your channel IDReduplicate
This should be the top answer. Crazy that YouTube doesn't have an official way to distinguish.Ressieressler
I love how SO has become unofficial documentation for services that could easily make this information readily available.Sleepless
@coco0419 may you share the algorithm you used to perform such an URL search? It could useful for people to rerun it regularly to check if new prefixes of playlist ids are introduced.Maclaine
@BenjaminLoison I have created a demo code, in TypeScript. Added at the end of the body of the post. You can check by entering your API key and channel ID. However, some prefixes are limited, e.g., Members-only short videos, so appropriate channel selection is necessary.Soho
C
23

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.

Crawler answered 11/5, 2022 at 8:17 Comment(16)
This is correct, requires no 3rd party solution :)Typewriting
What happens when someone imports the short as https://www.youtube.com/watch?v=pKML4pZozDYTypewriting
@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.Crawler
@JoostSchuur Is there a way I can programmatically make a request? I tried fetch but CORS comes in betweenJuline
BTW, I added a feature request for this a while back. If others want to chime in: issuetracker.google.com/issues/232112727. A Google dev says they 'added this to the feature request list' as of May 2022.Crawler
@UsmanSabuwala CORS hasn't been an issue for me. I just run res = await fetch(shortsUrl, { method: 'head' }) and check res?.url?.startsWith(shortsUrl)Crawler
Doesn't seem like it works as of Feb 2023, even with "follow redirects off", it shows 200 nowWreckage
@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.Crawler
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?Ommatidium
@Ommatidium Not sure why this would be region specific. If you visit youtube.com/shorts/B-s71n0dHUk in a browser, do you not get redirected to 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.Crawler
@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.Ommatidium
@Ommatidium I can't quite replicate that. Even in incognito mode, when VPN'd to Germany, if i visit a shorts URL (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.Crawler
hahah, sorry you will hit captchaPhotoactive
@DylanB You won't hit a captcha doing a HEAD HTTP request and looking at the status code. That doesn't return any HTML that could contain a captcha. It only returns HTTP headers. I use this method in production at scale to identify Shorts and haven't had any problems with it.Crawler
Started to get 204s from this endpoint (on the couple I looked at, it was for longs, not shorts). Not sure if this is just an alternate response or a rate limit.Carping
This happens for both longs and shorts, seems to be a form of rate limit.Carping
M
13

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=="
        }
    ]
}
Maclaine answered 20/2, 2022 at 13:12 Comment(4)
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?Greenlet
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'Greenlet
Indeed my bad, I'm not accustomed to watch/work with YouTube shorts, I updated my answer :)Maclaine
Created a script which would loop around the channel and get you all the shorts links. gist.github.com/ankitahuja0508/5737e70c2294e6badcb2a7f08798765dAgma
E
11

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.
Exoskeleton answered 16/2, 2023 at 18:25 Comment(0)
M
2

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
Madisonmadlen answered 5/10, 2022 at 5:33 Comment(0)
L
2

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("https://www.googleapis.com/youtube/v3/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}

Lucillelucina answered 27/8, 2023 at 9:54 Comment(3)
What's BASE_URL? Is this ChatGPT? This isn't how you normally query the data API. Type doesn't have a 'short' option in google's search.listGerri
My bad I must have forgotten to update BASE_URL with the actual URL, I'll update that now. Type dose not have a 'short' option in google search list documentation, but it works. I don't know why they have not updated the documentation.Lucillelucina
@Lucillelucina Do you know if there's a type that only will return the regular long form videos (no shorts)?Percipient
A
1

For anyone still looking for a solution here is my approach using axios. Since a head request to the "/shorts/" url for a video that is NOT a short will still result in a status 200 response from axios I basically return the path value in request to see if its a redirect.

async function is_short(id) {
  try {
    const url = `https://www.youtube.com/shorts/${id}`
    const response = await axios.head(url)
    const path = response.request.path
    return (path.includes('/shorts/'))
  }
  catch (e) {
    return false
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.5.1/axios.min.js"></script>
Aletaaletha answered 29/9, 2023 at 18:15 Comment(0)
C
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?

Classroom answered 13/10, 2022 at 7:9 Comment(1)
It looks like it depends on the environment. You can check the bug report for more information: github.com/axios/axios/issues/3924 In short, XmlHttpRequests do automatically redirects, used in Node you can configure the behavior with "maxRedirects".Docker
B
0

Here's a working function in PHP based off @JoostSchuur's answer.

function isYouTubeShort($videoId) {
    $url = "https://www.youtube.com/shorts/" . $videoId;
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // Don't follow redirects

    // Execute the request
    curl_exec($ch);
    $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $redirectUrl = curl_getinfo($ch, CURLINFO_REDIRECT_URL);

    curl_close($ch);

    // If the response code is 200 and there's no redirection, it's a Short
    return ($responseCode == 200 && empty($redirectUrl));
}

// Example usage
$videoId = "hKwrn5-7FjQ";
if(isYouTubeShort($videoId)) {
    echo "This is a YouTube Short.";
} else {
    echo "This is not a YouTube Short.";
}
Bari answered 26/10, 2023 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.