Building with the YouTube Data API? The first thing you need is a Channel ID. Here is exactly how to get one — and how to resolve any URL format to the correct ID.
The YouTube Data API v3 uses Channel IDs as the primary identifier for all channel-level operations. When you want to fetch a channel's metadata, list its videos, or check its statistics, you need the Channel ID — not the display name, not the handle, not the custom URL.
A Channel ID looks like this:
UCBcRF18a7Qf58cCRy5xuWwQ
Always starts with UC. Always 24 characters. Permanent — it never changes even if the channel renames or updates its handle.
If you try to query the API with a display name like "MKBHD" or a handle like @mkbhd, most endpoints will return nothing. The Channel ID is the correct input.
For one-off lookups or getting a quick Channel ID before you start coding:
This is the fastest way when you just need the ID and do not want to set up API authentication first.
Once you have an API key, you can resolve Channel IDs programmatically. Here are the methods:
YouTube rolled out @handles in 2022 as the new standard channel identifier. To resolve a handle to a Channel ID:
GET https://www.googleapis.com/youtube/v3/channels
?part=id
&forHandle=@mkbhd
&key=YOUR_API_KEY
Response:
{
"kind": "youtube#channelListResponse",
"items": [
{
"kind": "youtube#channel",
"etag": "...",
"id": "UCBcRF18a7Qf58cCRy5xuWwQ"
}
]
}
Include the @ symbol in forHandle. Strip any URL prefix — pass @mkbhd, not https://youtube.com/@mkbhd.
For channels using the older /user/ URL format:
GET https://www.googleapis.com/youtube/v3/channels
?part=id
&forUsername=marquesbrownlee
&key=YOUR_API_KEY
Note: forUsername is for legacy /user/ channels only. It does not work for @handles or /c/ custom URLs.
If you already have what you think is a Channel ID, verify it:
GET https://www.googleapis.com/youtube/v3/channels
?part=snippet
&id=UCBcRF18a7Qf58cCRy5xuWwQ
&key=YOUR_API_KEY
This returns the channel name, description, and metadata. If items is empty, the ID is wrong.
Here is a practical function that handles all URL formats:
import re
import requests
API_KEY = "your_api_key_here"
YT_API = "https://www.googleapis.com/youtube/v3/channels"
def get_channel_id(url: str) -> str | None:
"""
Resolve any YouTube channel URL to its Channel ID.
Handles /channel/, @handle, /c/, and /user/ formats.
"""
# /channel/ URL — ID is directly in the URL
match = re.search(r"youtube\.com/channel/(UC[a-zA-Z0-9_-]{22})", url)
if match:
return match.group(1)
# @handle format
match = re.search(r"youtube\.com/(@[^/?]+)", url)
if match:
handle = match.group(1)
resp = requests.get(YT_API, params={"part": "id", "forHandle": handle, "key": API_KEY})
items = resp.json().get("items", [])
return items[0]["id"] if items else None
# Legacy /user/ format
match = re.search(r"youtube\.com/user/([^/?]+)", url)
if match:
username = match.group(1)
resp = requests.get(YT_API, params={"part": "id", "forUsername": username, "key": API_KEY})
items = resp.json().get("items", [])
return items[0]["id"] if items else None
# /c/ custom URL — no direct API resolution, fallback needed
return None
# Usage
channel_id = get_channel_id("https://youtube.com/@mkbhd")
print(channel_id) # UCBcRF18a7Qf58cCRy5xuWwQ
The /c/ custom URL format is the one edge case the YouTube Data API cannot resolve directly. There is no forCustomUrl parameter in the Channels endpoint.
Options for /c/ URLs:
1. channelid.app — resolves /c/ URLs by fetching the channel page
2. Fetch the channel page HTML and extract "channelId" from the source
3. Ask the channel owner for their Channel ID (they can find it in YouTube Studio)
For production code handling arbitrary user input, combining the API (for @handles and /user/) with a fallback for /c/ URLs gives the best coverage.
| Error | Cause | Fix |
|---|---|---|
items: [] (empty) |
Wrong or nonexistent ID/handle | Verify the URL on channelid.app first |
403 Forbidden |
API key missing or invalid | Check your key in Google Cloud Console |
403 quotaExceeded |
Daily quota hit (10,000 units/day) | Cache IDs — Channels.list costs 1 unit |
400 Bad Request |
Wrong parameter (e.g. using forUsername with a handle) | Match parameter to URL format |
The YouTube Data API has a daily quota of 10,000 units. The channels.list endpoint with part=id costs 1 unit per call — cheap.
For bulk lookups, batch up to 50 IDs per request:
GET .../channels?part=snippet&id=UC1,UC2,UC3,...UC50&key=API_KEY
Cache results — Channel IDs never change.
The free tier gives 10,000 quota units per day, which is plenty for development and moderate production use.
To use the YouTube Data API:
forHandle=@channelname in the Channels endpointforUsername=usernameid parameterCache your Channel IDs — they are permanent and do not need to be re-fetched.
Paste any channel URL — @handle, /c/, /channel/, or /user/ format — and get the Channel ID in one click.
Try channelid.app — Free