4

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"
      }
    ]
  }
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Anthony Battaglia
  • 2,499
  • 1
  • 12
  • 8
  • Seems duplicated with [this answered StackOverflow question](https://stackoverflow.com/q/74323173). – Benjamin Loison Nov 07 '22 at 15:23
  • Note that, while you can't fetch a channel given a handle, the handle itself is stored inside the [channel](https://developers.google.com/youtube/v3/docs/channels/list) response (`channel -> snippet -> customUrl`). – Ben Feb 15 '23 at 22:58

5 Answers5

4

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. ⚡kerooke@fountain.fm.",
        "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"
      }
    }
  ]
}
nikicat
  • 298
  • 3
  • 10
  • Confirmed. this is the right answer. – goodhyun Jan 10 '23 at 01:10
  • 3
    Nah, if the handle you want was not unique enough, you would get the most popular channel with the keyword instead. For example, https://www.youtube.com/@illustrator will give you Adobe Illustrator channel. – goodhyun Jan 13 '23 at 01:07
1

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

FullStackFool
  • 1,071
  • 9
  • 15
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];
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
goodhyun
  • 4,814
  • 3
  • 33
  • 25
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
Community
  • 1
  • 1
wholehope
  • 41
  • 4
0

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!

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Chen W
  • 119
  • 2
  • 12