Documentation Index
Fetch the complete documentation index at: https://mintlify.com/faraasaaay/innertube-v2/llms.txt
Use this file to discover all available pages before exploring further.
Overview
YTItem is a sealed class that acts as the common supertype for every piece of content returned by the InnerTube API. Whenever a method returns a mixed list of content — such as search results or artist sections — it returns List<YTItem>, and you use a when expression to handle each concrete type.
sealed class YTItem {
abstract val id: String
abstract val title: String
abstract val thumbnail: String?
abstract val explicit: Boolean
abstract val shareLink: String
}
There are four concrete subtypes:
| Subtype | Represents |
|---|
SongItem | An individual track (audio or music video) |
AlbumItem | An album or EP (links to a browse page and a playlist) |
PlaylistItem | A user playlist or auto-generated playlist (radio, mix) |
ArtistItem | A YouTube Music artist channel |
Shared Fields
All four subtypes inherit these abstract members from YTItem:
| Field | Type | Description |
|---|
id | String | Primary identifier. Meaning varies by subtype (see below). |
title | String | Display name of the item. |
thumbnail | String? | URL of the best-available thumbnail image. |
explicit | Boolean | true if the content carries an explicit label. |
shareLink | String | A shareable music.youtube.com URL computed for each subtype. |
SongItem
Represents a single track — either a pure audio track (MUSIC_VIDEO_TYPE_ATV) or a music video.
data class SongItem(
override val id: String, // videoId (e.g. "dQw4w9WgXcQ")
override val title: String,
val artists: List<Artist>,
val album: Album? = null,
val duration: Int? = null, // seconds
val musicVideoType: String? = null,
val chartPosition: Int? = null,
val chartChange: String? = null,
override val thumbnail: String,
override val explicit: Boolean = false,
val endpoint: WatchEndpoint? = null,
val setVideoId: String? = null,
val libraryAddToken: String? = null,
val libraryRemoveToken: String? = null,
val historyRemoveToken: String? = null,
val viewCountText: String? = null,
) : YTItem()
| Field | Type | Description |
|---|
id | String | The YouTube video ID. |
artists | List<Artist> | One or more artists. Each has name: String and optional id: String. |
album | Album? | Associated album (name and id). Null for standalone videos. |
duration | Int? | Track length in seconds. |
musicVideoType | String? | Internal type string from YouTube (e.g., MUSIC_VIDEO_TYPE_ATV). |
endpoint | WatchEndpoint? | Watch endpoint for initiating playback. |
setVideoId | String? | Required when removing a song from a specific playlist position. |
libraryAddToken | String? | Feedback token to add this song to the library. |
libraryRemoveToken | String? | Feedback token to remove this song from the library. |
historyRemoveToken | String? | Feedback token to remove this song from history. |
viewCountText | String? | Localised view count string (e.g., "1.2B views"). |
shareLink | String | https://music.youtube.com/watch?v={id} |
Computed property:
val isVideoSong: Boolean
get() = musicVideoType != null && musicVideoType != MUSIC_VIDEO_TYPE_ATV
isVideoSong is true when the track is a music video rather than a pure audio track. Use this to separate songs from videos in search results.
AlbumItem
Represents an album or EP browse page.
data class AlbumItem(
val browseId: String, // e.g. "MPREb_..."
val playlistId: String, // e.g. "OLAK5uy_..."
override val id: String = browseId, // aliases browseId
override val title: String,
val artists: List<Artist>?,
val year: Int? = null,
override val thumbnail: String,
override val explicit: Boolean = false,
val description: String? = null,
) : YTItem()
| Field | Type | Description |
|---|
browseId | String | Browse ID used with YouTube.album(browseId). |
playlistId | String | Playlist ID used with YouTube.albumSongs(playlistId). |
id | String | Aliases browseId. |
artists | List<Artist>? | List of album artists. May be null for compilations. |
year | Int? | Release year. |
description | String? | Album description text. |
shareLink | String | https://music.youtube.com/playlist?list={playlistId} |
PlaylistItem
Represents a user-created or auto-generated playlist.
data class PlaylistItem(
override val id: String,
override val title: String,
val author: Artist?,
val songCountText: String?,
override val thumbnail: String?,
val playEndpoint: WatchEndpoint?,
val shuffleEndpoint: WatchEndpoint?,
val radioEndpoint: WatchEndpoint?,
val isEditable: Boolean = false,
val description: String? = null,
) : YTItem()
| Field | Type | Description |
|---|
id | String | Playlist ID (e.g., PLxxxx). |
author | Artist? | Playlist creator. |
songCountText | String? | Localised count string (e.g., "42 songs"). |
playEndpoint | WatchEndpoint? | Endpoint to start playing the playlist. |
shuffleEndpoint | WatchEndpoint? | Endpoint to start a shuffle of the playlist. |
radioEndpoint | WatchEndpoint? | Endpoint to start a radio based on the playlist. |
isEditable | Boolean | true if the signed-in user can edit this playlist. |
description | String? | Playlist description. |
explicit | Boolean | Always false for playlists. |
shareLink | String | https://music.youtube.com/playlist?list={id} |
ArtistItem
Represents a YouTube Music artist channel.
data class ArtistItem(
override val id: String,
override val title: String,
override val thumbnail: String?,
val channelId: String? = null,
val playEndpoint: WatchEndpoint? = null,
val shuffleEndpoint: WatchEndpoint?,
val radioEndpoint: WatchEndpoint?,
val subtext: String? = null,
) : YTItem()
| Field | Type | Description |
|---|
id | String | The artist browse ID (e.g., UCxxxxxx). |
channelId | String? | The underlying YouTube channel ID for subscriptions. |
playEndpoint | WatchEndpoint? | Endpoint to start playing a top track. |
shuffleEndpoint | WatchEndpoint? | Endpoint to shuffle the artist’s songs. |
radioEndpoint | WatchEndpoint? | Endpoint to start an artist radio. |
subtext | String? | Subscriber count or other secondary text. |
explicit | Boolean | Always false for artists. |
shareLink | String | https://music.youtube.com/channel/{id} |
Helper Data Classes
Two small data classes are used as nested structures across subtypes:
data class Artist(
val name: String,
val id: String?, // null when the artist has no browse page
)
data class Album(
val name: String,
val id: String, // browseId of the album
)
Handling All Four Subtypes
Use a when expression to exhaustively dispatch on YTItem. Because YTItem is sealed, the compiler enforces that all cases are covered:
fun describe(item: YTItem): String = when (item) {
is SongItem -> buildString {
append("🎵 ${item.title}")
append(" by ${item.artists.joinToString { it.name }}")
item.album?.let { append(" · ${it.name}") }
item.duration?.let { append(" (${it / 60}:${(it % 60).toString().padStart(2, '0')})") }
if (item.isVideoSong) append(" [Video]")
if (item.explicit) append(" 🅴")
}
is AlbumItem -> buildString {
append("💿 ${item.title}")
item.artists?.let { append(" by ${it.joinToString { a -> a.name }}") }
item.year?.let { append(" ($it)") }
}
is PlaylistItem -> buildString {
append("📋 ${item.title}")
item.author?.let { append(" · ${it.name}") }
item.songCountText?.let { append(" · $it") }
}
is ArtistItem -> buildString {
append("👤 ${item.title}")
item.subtext?.let { append(" · $it") }
}
}
Filter Extension Functions
Three extension functions on List<T : YTItem> let you filter results without manual when expressions:
// Remove explicit tracks (e.g. for parental controls)
fun <T : YTItem> List<T>.filterExplicit(enabled: Boolean = true): List<T>
// Remove music video SongItems, keeping only pure audio tracks
fun <T : YTItem> List<T>.filterVideoSongs(disableVideos: Boolean = false): List<T>
// Remove YouTube Shorts from playlist results (id starts with "SS")
fun <T : YTItem> List<T>.filterYoutubeShorts(enabled: Boolean = false): List<T>
Usage example:
viewModelScope.launch {
YouTube.search("pop hits", SearchFilter.FILTER_SONG)
.onSuccess { result ->
val filtered = result.items
.filterExplicit(enabled = userPrefs.hideExplicit)
.filterVideoSongs(disableVideos = userPrefs.audioOnlyMode)
adapter.submitList(filtered)
}
}
filterExplicit filters on the explicit field of each YTItem. Note that AlbumItem.explicit is currently always false because the YouTube API does not reliably surface the explicit badge for albums in all response formats.