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.
| Property | Type | Description |
|---|
locale | YouTubeLocale | Country (gl) and language (hl) sent with every request. Defaults to the device locale. |
visitorData | String? | Opaque visitor session token obtained from YouTube.refreshVisitorData(). Required for some endpoints. |
dataSyncId | String? | Account data-sync ID used for authenticated browse calls. |
cookie | String? | Full raw cookie string (e.g., SAPISID=...). Setting this enables authenticated requests where loginSupported = true on the chosen client. |
proxy | Proxy? | A java.net.Proxy. Setting this recreates the HTTP client with the new proxy. |
proxyAuth | String? | Proxy-Authorization header value for authenticated proxies. |
useLoginForBrowse | Boolean | When true, all browse and search calls attach the login cookie even if loginSupported is not set on the client. |
ipVersion | IpVersion | Forces 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
Search
| Method | Returns | Description |
|---|
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
| Method | Returns | Description |
|---|
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
| Method | Returns | Description |
|---|
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
| Method | Returns | Description |
|---|
playlist(playlistId) | Result<PlaylistPage> | Full playlist page. |
playlistContinuation(continuation) | Result<PlaylistContinuationPage> | Load more songs from a playlist. |
createPlaylist(title) | String | Create 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
| Method | Returns | Description |
|---|
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
| Method | Returns | Description |
|---|
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
| Method | Returns | Description |
|---|
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() | Unit | Clears 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.