Skip to main content

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

YouTube is a Kotlin object (singleton) — there is exactly one instance for the lifetime of your application. It is the only entry point you need for all InnerTube operations: searching, browsing albums and artists, resolving playback streams, managing playlists, and more.
// Access is always through the singleton — no constructor needed
YouTube.locale = YouTubeLocale(gl = "US", hl = "en")
YouTube.cookie = "SAPISID=..."

Architecture

YouTube works as a two-layer stack:
Your App Code


YouTube  (high-level: parses JSON → typed Page objects)


InnerTube  (low-level: Ktor/OkHttp HTTP client, request bodies, headers)


https://music.youtube.com/youtubei/v1/
  • YouTube holds a private InnerTube instance. It calls InnerTube methods, deserialises the raw kotlinx.serialization response objects, and maps renderer trees into clean page models like SearchResult, AlbumPage, and ArtistPage.
  • InnerTube owns the Ktor HttpClient (backed by OkHttp), builds request bodies, attaches auth headers, and applies an exponential-backoff retry wrapper for transient IOExceptions. You never need to touch InnerTube directly.

Configuring the YouTube Object

All configuration is done by setting properties on YouTube. Each property is transparently delegated to the underlying InnerTube instance.
PropertyTypeDescription
localeYouTubeLocaleCountry (gl) and language (hl) sent with every request. Defaults to the device locale.
visitorDataString?Opaque visitor session token obtained from YouTube.refreshVisitorData(). Required for some endpoints.
dataSyncIdString?Account data-sync ID used for authenticated browse calls.
cookieString?Full raw cookie string (e.g., SAPISID=...). Setting this enables authenticated requests where loginSupported = true on the chosen client.
proxyProxy?A java.net.Proxy. Setting this recreates the HTTP client with the new proxy.
proxyAuthString?Proxy-Authorization header value for authenticated proxies.
useLoginForBrowseBooleanWhen true, all browse and search calls attach the login cookie even if loginSupported is not set on the client.
ipVersionIpVersionForces DNS resolution to IPV4, IPV6, or AUTO. Setting this recreates the HTTP client.
Call YouTube.refreshVisitorData() once on app start. It fetches a fresh visitor token from YouTube and automatically stores it in YouTube.visitorData. Many endpoints return richer results with a valid visitor token present.

Most Methods Are Suspend Functions

Almost every public method on YouTube is a Kotlin suspend function that must be called from inside a coroutine or another suspend function. The only exception is createPlaylist, which uses runBlocking internally and can be called from any context (though it blocks the calling thread).
// ✅ Inside a coroutine scope
viewModelScope.launch {
    val result = YouTube.search("Daft Punk", SearchFilter.FILTER_SONG)
}

// ❌ This will not compile — search is a suspend function
val result = YouTube.search("Daft Punk", SearchFilter.FILTER_SONG)

// ✅ createPlaylist is NOT suspend — it uses runBlocking internally
val playlistId: String = YouTube.createPlaylist("My Playlist")

Return Type: Result<T>

Every method returns Result<T>. Use .getOrThrow(), .getOrNull(), or .onSuccess / .onFailure to handle results:
viewModelScope.launch {
    val result: Result<SearchResult> = YouTube.search("Daft Punk", SearchFilter.FILTER_SONG)

    result
        .onSuccess { searchResult ->
            val songs = searchResult.items.filterIsInstance<SongItem>()
            println("Found ${songs.size} songs")
            songs.forEach { println("  ${it.title}${it.artists.joinToString { a -> a.name }}") }

            // If there are more pages, searchResult.continuation is non-null
            searchResult.continuation?.let { token ->
                val nextPage = YouTube.searchContinuation(token).getOrNull()
                // ... handle next page
            }
        }
        .onFailure { error ->
            println("Search failed: ${error.message}")
        }
}

Method Categories

MethodReturnsDescription
search(query, filter)Result<SearchResult>Filtered search (songs, albums, artists, playlists, videos).
searchContinuation(continuation)Result<SearchResult>Load the next page of search results.
searchSummary(query)Result<SearchSummaryPage>Multi-section summary across all content types.
searchSuggestions(query)Result<SearchSuggestions>Autocomplete queries and recommended items.

Browse

MethodReturnsDescription
album(browseId, withSongs)Result<AlbumPage>Full album page including songs and other versions.
albumSongs(playlistId, album)Result<List<SongItem>>All songs for an album, auto-paging through continuations.
artist(browseId)Result<ArtistPage>Artist page with sections, subscriber count, and description.
artistItems(endpoint)Result<ArtistItemsPage>A specific artist section (albums, singles, etc.).
artistItemsContinuation(continuation)Result<ArtistItemsContinuationPage>Load more items from an artist section.
explore()Result<ExplorePage>The Explore page.
newReleaseAlbums()Result<List<AlbumItem>>New release albums.
moodAndGenres()Result<List<MoodAndGenres>>Mood and genre browse tiles.
browse(browseId, params)Result<BrowseResult>Generic browse endpoint.
home(continuation, params)Result<HomePage>Home feed, with optional continuation.
getChartsPage(continuation)Result<ChartsPage>Music charts.

Player

MethodReturnsDescription
player(videoId, playlistId, client, signatureTimestamp, poToken)Result<PlayerResponse>Raw player response for a video.
next(endpoint, continuation)Result<NextResult>Up-next queue and related items for a video.
lyrics(endpoint)Result<String?>Lyrics text for a song.
related(endpoint)Result<RelatedPage>Related content shelf for a video.
queue(videoIds, playlistId)Result<List<SongItem>>Build a playback queue.
transcript(videoId)Result<String>Video transcript text.
getMediaInfo(videoId)Result<MediaInfo>Video metadata (title, author, view count, likes/dislikes).
registerPlayback(playlistId, playbackTracking)Result<Unit>Report playback to YouTube for history tracking.

Playlists

MethodReturnsDescription
playlist(playlistId)Result<PlaylistPage>Full playlist page.
playlistContinuation(continuation)Result<PlaylistContinuationPage>Load more songs from a playlist.
createPlaylist(title)StringCreate a new playlist; returns playlist ID. Not a suspend function — uses runBlocking internally.
renamePlaylist(playlistId, name)Result<Unit>Rename an existing playlist.
deletePlaylist(playlistId)Result<Unit>Delete a playlist.
addToPlaylist(playlistId, videoId)Result<Unit>Add a video to a playlist.
addPlaylistToPlaylist(playlistId, addPlaylistId)Result<Unit>Add all songs from one playlist into another.
removeFromPlaylist(playlistId, videoId, setVideoId)Result<Unit>Remove a song from a playlist.
moveSongPlaylist(playlistId, setVideoId, successorSetVideoId)Result<Unit>Reorder songs in a playlist.
uploadCustomThumbnailLink(playlistId, image)Result<Unit>Upload a custom thumbnail for a playlist.
removeThumbnailPlaylist(playlistId)Result<Unit>Remove a custom thumbnail from a playlist.

Library

MethodReturnsDescription
library(browseId, tabIndex)Result<LibraryPage>A library tab (songs, albums, artists, playlists).
libraryContinuation(continuation)Result<LibraryContinuationPage>Load more library items.
libraryRecentActivity()Result<LibraryPage>Recently played items.
musicHistory()Result<HistoryPage>Watch/listen history.

Social

MethodReturnsDescription
likeVideo(videoId, like)Result<Unit>Like or unlike a video.
likePlaylist(playlistId, like)Result<Unit>Like or unlike a playlist.
subscribeChannel(channelId, subscribe)Result<Unit>Subscribe to or unsubscribe from a channel.
comments(videoId)Result<Pair<List<CommentThreadRenderer>, String?>>First page of comments and a continuation token.
commentContinuation(continuationToken)Result<Pair<List<CommentThreadRenderer>, String?>>Load more comments.
commentReplies(replyToken)Result<Pair<List<CommentRenderer>, String?>>Load replies for a comment thread.
feedback(tokens)Result<Boolean>Send feedback (e.g., add/remove from library via token).

Account

MethodReturnsDescription
accountInfo()Result<AccountInfo>Signed-in account name and avatar.
visitorData()Result<String>Fetch a fresh visitor data token.
refreshVisitorData()Result<String>Fetch and store a fresh visitor data token.
clearGuestSession()UnitClears visitorData and dataSyncId. Not a suspend function.
addSongToLibrary(videoId)Result<Boolean>Add a song to the signed-in user’s library.
removeSongFromLibrary(videoId)Result<Boolean>Remove a song from the signed-in user’s library.
toggleSongLibrary(videoId, addToLibrary)Result<Boolean>Conditionally add or remove a song from library.

Concurrency Safety

YouTube is a Kotlin object with shared mutable properties, so you should avoid mutating locale, cookie, or other config properties from multiple coroutines simultaneously. However, concurrent API calls are safe: InnerTube uses an OkHttp ConnectionPool (10 idle connections, 5-minute keep-alive) and Ktor’s async request model — multiple YouTube.* calls can run in parallel without data races on the HTTP layer.

Build docs developers (and LLMs) love