YouTube Channel ID vs Handle vs Custom URL: How to Find It

Published Updated
YouTube has three channel identifiers in circulation at once. Here is how to tell them apart, which the API accepts, and how to resolve one to another.

A YouTube channel ID is the permanent identifier beginning UC, visible in URLs of the form youtube.com/channel/UCxxxxxxxxxxxxxxxxxxxxxx. A handle is the @name form the creator chooses and can change. A custom URL is the older /c/name or /user/name style. Only the channel ID is stable, and it is what the Data API addresses.

YouTube is unusual in running three identifier styles simultaneously, each introduced at a different point and none fully retired. That is why so many YouTube integrations break on input parsing rather than on anything interesting.

What are the three YouTube identifiers?

They look nothing alike, which at least makes them easy to tell apart once you know the shapes.

Channel IDHandleCustom URL (legacy)
FormUC + 22 characters@name/c/name or /user/name
URL/channel/UCxxxx.../@name/c/name, /user/name
Can it change?No, permanentYes, creator can change itYes, and may stop resolving
Unique?Yes, globallyYes, while heldYes, while held
Data API filteridforHandleforUsername for /user/ only
Safe to store?YesNo, display onlyNo

The channel ID is the one to build on. It always begins UC and runs to 24 characters in total, using a base64-style alphabet that includes letters, digits, hyphens and underscores. Because it contains non-digits, it is not a number and nobody is tempted to parse it as one, which spares YouTube developers the precision-loss bug that plagues Facebook, Instagram and TikTok integrations.

Handles are the current creator-facing identifier, written @name and appearing in URLs as /@name. A creator can change a handle, and a released handle may become available to someone else, so a stored handle is not a reliable long-term reference to a particular channel.

Custom URLs are the legacy layer. The /user/name form dates from when YouTube accounts had usernames; the /c/name form came later as a vanity option. Both still appear in old links, documents and databases. Neither is being issued to new channels, but you will keep encountering them in input.

How do you find a channel ID from a URL?

Depends which of the three shapes you are holding, which is the whole reason to know the shapes.

If the URL is already /channel/UC...

Copy the segment starting UC. That is the channel ID, no resolution needed. Strip any trailing path or query parameters, since YouTube URLs routinely arrive with ?si= or similar appended.

If the URL is a handle or custom URL

You need to resolve it. There is no transformation from @name to a UC string; the mapping lives in YouTube's records and has to be looked up.

The manual route is to open the channel and read the page source. YouTube embeds the channel ID in the HTML, including in canonical link and meta tags, because the page needs to reference itself canonically. Searching the source for UC followed by 22 characters generally finds it. Fine for one channel, impractical for a list, and vulnerable to YouTube changing its markup.

The quicker route is to paste the URL into the YouTube channel ID finder, which handles all three URL shapes and needs no login or API key. This is the pragmatic option when you are converting a spreadsheet of channel links into stable identifiers.

How does the YouTube Data API resolve a handle?

Properly, and this is where YouTube is better documented than its peers. Google's channels.list method accepts filter parameters that cover each identifier style, and the relevant ones are clearly specified.

The forHandle parameter returns the channel for a given handle, and per Google's documentation the @ prefix is optional, so both GoogleDevelopers and @GoogleDevelopers are accepted. The forUsername parameter returns the channel associated with a legacy YouTube username, which is the route for /user/name URLs. The id parameter takes a comma-separated list of channel IDs, which is how you batch lookups once you have IDs. And mine returns channels owned by the authenticated user, requiring an authorised request.

Two constraints matter in practice. First, channels.list requires exactly one filter parameter; combining them returns an error, so you must branch on input type before building the request rather than passing several filters hopefully. Second, a call to this method has a quota cost of 1 unit, which is cheap, so bulk resolution is viable within normal quota as long as you batch id lookups rather than making one request per channel.

One gap worth knowing: there is no documented filter for the /c/name custom URL form. forUsername covers /user/ URLs, not /c/ ones. If your input contains /c/ URLs, the API route will not resolve them directly and you will need to fall back to loading the channel page or using a lookup that does.

Why does YouTube have three identifier styles at all?

Accumulated history, mostly, and a reluctance to break old links. Each style was introduced to solve a problem the previous one had, and each was left in place rather than retired.

The UC channel ID is the underlying permanent key and has always existed. It is unmemorable by design, which is fine for machines and poor for humans printing a URL on a business card. Custom URLs addressed that, first through the /user/ form carried over from YouTube's account system and later through /c/ vanity names. Handles came later and unified the human-readable layer into a single @name namespace consistent with how other platforms work.

The result is three layers in simultaneous circulation, where older channels may be reachable by all three and newer ones only by handle and ID. Your parser has to cope with whatever a user pastes, and users paste whatever their browser showed them, which depends on the channel's age.

What do you need the channel ID for?

Everything programmatic, and several things that are not.

Data API calls address channels by ID: listing uploads, reading statistics, fetching playlists, resolving the uploads playlist to enumerate videos. The RSS feed for a channel, which remains a genuinely useful low-friction way to track new uploads without an API key, is keyed on the channel ID rather than the handle. Subscribe links and embed configurations take the ID. Analytics pipelines should key on it so that a handle change does not fragment a channel's history.

There is also a neat structural detail worth knowing: a channel's uploads playlist ID is conventionally derived from its channel ID by replacing the UC prefix with UU. That saves an API call when you want a channel's videos, though as an undocumented convention rather than a promise, do not build something fragile on it.

Downloading is a separate matter entirely. Saving a specific video starts from the video URL, not from a channel identifier, so the two workflows do not overlap. If you work across platforms, the equivalent lookups are Instagram user ID, TikTok user ID and Facebook ID, and none of them is as cleanly documented as YouTube's.

Which identifier should you store?

The channel ID, as the primary key, every time. Store the handle alongside it as display metadata and refresh it periodically, treating it as a label rather than a reference.

The reasoning is the same as on every platform but has a specific YouTube edge to it: because three identifier styles exist, a dataset storing "whatever URL the user gave us" ends up with three kinds of row and no way to query across them. Normalising everything to a channel ID at ingestion time means one column, one format, one lookup path.

Resolve at the edge of your system rather than in the middle of it. Accept any of the three URL shapes from users, resolve immediately, store the ID, and have the rest of your code deal only with UC strings. That is a small amount of input handling in one place instead of three identifier styles leaking through every layer.

If you are also handling TikTok links in the same pipeline, note that TikTok's shortened mobile URLs hide their destination and need expanding first with the TikTok web link converter, which is a comparable input-normalisation step.

Frequently asked questions

Does a YouTube channel ID ever change?

No. The UC identifier is assigned when the channel is created and stays with it permanently, surviving handle changes, renames and rebrands. That permanence is why it belongs in your database as the primary key while the handle belongs there only as a display label you refresh.

Can the Data API resolve a /c/ custom URL?

Not directly. Google documents forHandle for handles and forUsername for legacy YouTube usernames, which covers /user/ URLs, but there is no documented filter for the /c/ vanity form. For those, load the channel page and read the ID from the source, or use a lookup tool that handles all three URL shapes.

Can I pass several filters to channels.list at once?

No. Google's documentation specifies that channels.list requires exactly one filter parameter, and combining id, forHandle, forUsername or mine returns an error. Branch on your input type and build the appropriate single-filter request, rather than passing multiple filters and hoping one matches.

How much API quota does a channel lookup cost?

Google documents a call to channels.list as costing 1 quota unit, which makes bulk resolution practical. To use quota efficiently, batch lookups by passing a comma-separated list to the id parameter rather than issuing one request per channel, since the per-call cost applies whether you fetch one channel or several.

Is a YouTube handle unique?

It is unique while held, but not permanently assigned. A creator can change their handle, and a released handle may become available to another channel, so a stored handle can eventually point somewhere unintended. For any reference that needs to stay correct, store the channel ID and treat the handle as mutable.

Do I need an API key to find a channel ID?

Not for a one-off lookup. The channel ID is embedded in a public channel page's HTML, and a browser-based lookup reads it without credentials. Get an API key when your application needs to resolve channels at runtime or fetch channel data programmatically; for converting a list of links into IDs, a key is unnecessary overhead.