YouTube Data API Get Channel by Handle
Asked Answered
N

6

5

Introducing handles: A new way to identify your YouTube channel

Does the YouTube Data API support querying for a channel by it's @handle? This does not seem to be supported.

ex: https://www.youtube.com/@lionsgatemovies

forUsername param

GET https://www.googleapis.com/youtube/v3/channels?part=id,snippet&forUsername=@lionsgatemovies

{
  "kind": "youtube#channelListResponse",
  "etag": "RuuXzTIr0OoDqI4S0RU6n4FqKEM",
  "pageInfo": {
    "totalResults": 0,
    "resultsPerPage": 5
  }
}

id param

GET https://www.googleapis.com/youtube/v3/channels?part=id,snippet&id=@lionsgatemovies

{
  "kind": "youtube#channelListResponse",
  "etag": "RuuXzTIr0OoDqI4S0RU6n4FqKEM",
  "pageInfo": {
    "totalResults": 0,
    "resultsPerPage": 5
  }
}

None of the supported filter params seem to be appropriate:

{
  "error": {
    "code": 400,
    "message": "No filter selected. Expected one of: mySubscribers, forUsername, mine, managedByMe, categoryId, id",
    "errors": [
      {
        "message": "No filter selected. Expected one of: mySubscribers, forUsername, mine, managedByMe, categoryId, id",
        "domain": "youtube.parameter",
        "reason": "missingRequiredParameter",
        "location": "parameters.",
        "locationType": "other"
      }
    ]
  }
}
Narda answered 7/11, 2022 at 15:7 Comment(2)
Seems duplicated with this answered StackOverflow question. – Magnitude
Note that, while you can't fetch a channel given a handle, the handle itself is stored inside the channel response (channel -> snippet -> customUrl). – Solander
S
6

You can use Search API with q parameter set to @handle

curl \
  'https://youtube.googleapis.com/youtube/v3/search?part=snippet&maxResults=25&q=%40kevinrooke&type=channel&key=[YOUR_API_KEY]'

{
  "kind": "youtube#searchListResponse",
  "etag": "AYlro9VG2vMtdew4OQiWoQM8Rs0",
  "regionCode": "LT",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "ls9E_ctoa-RLsqznJwxWlHHIE1s",
      "id": {
        "kind": "youtube#channel",
        "channelId": "UCTdxV_ItCZMayyzGkw7P_qQ"
      },
      "snippet": {
        "publishedAt": "2017-05-27T03:56:38Z",
        "channelId": "UCTdxV_ItCZMayyzGkw7P_qQ",
        "title": "Kevin Rooke",
        "description": "Interviews with the builders bringing the Lightning Network to life. ⚑[email protected].",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/ytc/AMLnZu-SpmaNjx7KOMqs5Cr7ZthU60BaQApzt89_dHOlcg=s88-c-k-c0xffffffff-no-rj-mo"
          },
          "medium": {
            "url": "https://yt3.ggpht.com/ytc/AMLnZu-SpmaNjx7KOMqs5Cr7ZthU60BaQApzt89_dHOlcg=s240-c-k-c0xffffffff-no-rj-mo"
          },
          "high": {
            "url": "https://yt3.ggpht.com/ytc/AMLnZu-SpmaNjx7KOMqs5Cr7ZthU60BaQApzt89_dHOlcg=s800-c-k-c0xffffffff-no-rj-mo"
          }
        },
        "channelTitle": "Kevin Rooke",
        "liveBroadcastContent": "none",
        "publishTime": "2017-05-27T03:56:38Z"
      }
    }
  ]
}
Socle answered 23/12, 2022 at 18:13 Comment(4)
Confirmed. this is the right answer. πŸ₯‡ – Randy
Nah, if the handle you want was not unique enough, you would get the most popular channel with the keyword instead. For example, youtube.com/@illustrator will give you Adobe Illustrator channel. – Randy
or a list of completely unrelated channels in the case of @MauLerYT, among which is not included the URL of the channel itself. it works if you search for the full URL tho (youtube.com/@MauLerYT). Would have preferred to use the API, but I guess now they're just gonna have to deal with scraping because a 100 channel search will suck up your entire daily quota anyway so it's not like it would be useful if it even worked. This could have been a 1 quota point operation (or less). – Cheddite
funnier yet is the support page just says "oh the devs monitor stackoverflow". they deserve every bit of scraping they get – Cheddite
P
2

now you can use the new parameter forHandle (docs)

The forHandle parameter specifies a YouTube handle, thereby requesting the channel associated with that handle. The parameter value can be prepended with an @ symbol. For example, to retrieve the resource for the "Google for Developers" channel, set the forHandle parameter value to either GoogleDevelopers or @GoogleDevelopers.

Plourde answered 10/2 at 17:24 Comment(0)
O
1

As of this moment (17th Nov 2022), YouTube has yet to update the Data API with @handle support.

Obstinacy answered 17/11, 2022 at 17:1 Comment(0)
R
1

The channelId was scattered around in the Html. You can easily parse them after fetching the url with the handle.

const html = await(await fetch(url)).text()
const channelId = html.match(/(?<=channelId(":"|"\scontent="))[^"]+/g)[0];
Randy answered 13/1, 2023 at 5:30 Comment(0)
A
1

The official API doesn't support this and using the search API can return the most popular channel instead of the exact name match.

The best solution I have found after reading through all the stackoverflow posts and different Youtube APIs is to use Youtube.js to interface with InnerTube(Youtube's internal API) and resolve the channel url.

If you have the full channel url, there's a resolve url endpoint that will return an object with the id.

//innerTubeUtils.ts

import { Innertube } from "youtubei.js";

export async function getChannelFromUrl(url: string) {
  const innerTube = await Innertube.create(/* options */);
  const resolved = await innerTube.resolveURL(url);
  const channelId = resolved.payload.browseId;
  return channelId;
}

The payload you get back will a browseId property, which is the channelId.

Courtesy of ChunkyProgrammer for providing this solution!

Argenteuil answered 8/6, 2023 at 18:21 Comment(0)
R
0

Following is the python snippet while we are waiting for YouTube API's official support. This is inspired by goodhyun's wonderful thoughts.

import requests
import re

# return YouTube channel id via handle or False if failed
def scraping_get_channel_id_from_handle(handle:str):
    if handle.find('@') == -1:
        handle = '@' + handle

    url = 'https://www.youtube.com/' + handle
    resp = requests.get(url)

    if resp.status_code == 200:
        found = re.findall('<meta itemprop="channelId" content="([^"]*)"', resp.text)

        return found[0]
    else:
        return False
Rhyne answered 14/2, 2023 at 17:55 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.