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.

The Player API covers everything needed to stream audio, build a queue, display lyrics, and track playback. All methods are suspend functions on the YouTube singleton and return Result<T>.

YouTube.player()

Fetches a PlayerResponse for a video, including stream URLs and playability status.
suspend fun player(
    videoId: String,
    playlistId: String? = null,
    client: YouTubeClient,
    signatureTimestamp: Int? = null,
    poToken: String? = null,
): Result<PlayerResponse>
videoId
String
required
The YouTube video ID (e.g. "dQw4w9WgXcQ").
playlistId
String?
Optional playlist context ID. Pass the playlist ID when playing a song in a playlist for correct autoplay behaviour.
client
YouTubeClient
required
The client context to use. Common choices are YouTubeClient.WEB_REMIX (YouTube Music) and YouTubeClient.WEB. The client determines which stream formats are returned.
signatureTimestamp
Int?
Signature timestamp for cipher decoding. Required when using clients that return signature-protected stream URLs. Obtain from the player JavaScript.
poToken
String?
Proof-of-origin token for bot-check bypass. Leave null unless you have obtained a valid token for the client.

Returns

Result<PlayerResponse>
playabilityStatus.status
String
Playability indicator. Common values:
ValueMeaning
"OK"Streams are available
"LOGIN_REQUIRED"Requires an authenticated cookie
"AGE_CHECK_REQUIRED"Age-gated content
"UNPLAYABLE"Content is unavailable in the current region
"ERROR"Generic server-side error
streamingData.adaptiveFormats
List<Format>
Adaptive (DASH) audio and video streams. Each Format carries itag, url, mimeType, bitrate, contentLength, and codec details. Audio-only streams have audioQuality set.
streamingData.formats
List<Format>?
Combined (progressive) audio+video streams. Typically lower quality and not always present.
videoDetails
VideoDetails
Metadata including videoId, title, author, lengthSeconds, thumbnail, and viewCount.
playerConfig.audioConfig
AudioConfig?
Contains loudnessDb for volume normalisation and perceptualLoudnessDb.
playbackTracking
PlaybackTracking?
URLs for CPB/CPH playback tracking. Pass the primary URL string to registerPlayback().

Example

import com.music.innertube.YouTube
import com.music.innertube.models.YouTubeClient

val playerResponse = YouTube.player(
    videoId      = "dQw4w9WgXcQ",
    playlistId   = null,
    client       = YouTubeClient.WEB_REMIX,
).getOrThrow()

if (playerResponse.playabilityStatus.status == "OK") {
    val audioFormats = playerResponse.streamingData
        ?.adaptiveFormats
        ?.filter { it.mimeType.startsWith("audio/") }
        ?.sortedByDescending { it.bitrate }

    val bestAudioUrl = audioFormats?.firstOrNull()?.url
    println("Stream URL: $bestAudioUrl")
}

YouTube.next()

Fetches the playback queue (upcoming tracks) for a given watch endpoint, automatically following automix for infinite radio playback.
suspend fun next(
    endpoint: WatchEndpoint,
    continuation: String? = null,
): Result<NextResult>
endpoint
WatchEndpoint
required
Describes the current playback context. Common fields:
continuation
String?
Opaque continuation token from a previous NextResult.continuation. Pass null for the first call.

Returns

Result<NextResult>
title
String?
Queue title, e.g. the playlist name or "Recommended".
items
List<SongItem>
The list of upcoming tracks in the queue. When automix is triggered the method recursively resolves the automix endpoint and concatenates the results, so items may contain many more entries than a single API page.
currentIndex
Int?
Zero-based index of the currently-selected track within items, or null if not determinable.
lyricsEndpoint
BrowseEndpoint?
Endpoint to pass to lyrics() to fetch the lyrics for the current track.
Endpoint to pass to related() to fetch related songs, albums, and artists.
continuation
String?
Token for fetching more queue items. Pass this back as continuation on the same endpoint.
endpoint
WatchEndpoint
The effective watch endpoint used (may be the automix endpoint when automix was followed).

Example

import com.music.innertube.YouTube
import com.music.innertube.models.WatchEndpoint

val result = YouTube.next(
    WatchEndpoint(videoId = "dQw4w9WgXcQ")
).getOrThrow()

println("Queue title: ${result.title}")
result.items.forEachIndexed { i, song ->
    val marker = if (i == result.currentIndex) "▶" else " "
    println("$marker ${song.title}${song.artists.joinToString { it.name }}")
}

// Load lyrics for the current song
result.lyricsEndpoint?.let { ep ->
    val lyrics = YouTube.lyrics(ep).getOrNull()
    println(lyrics)
}

YouTube.queue()

Fetches SongItem metadata for a list of video IDs or an entire playlist, without setting up full playback context.
suspend fun queue(
    videoIds: List<String>? = null,
    playlistId: String? = null,
): Result<List<SongItem>>
videoIds
List<String>?
Up to YouTube.MAX_GET_QUEUE_SIZE (1000) video IDs. Provide either this or playlistId, not both.
playlistId
String?
A playlist ID to bulk-resolve. Provide either this or videoIds, not both.

Returns

Result<List<SongItem>> — a flat list of resolved song items in request order.
The constant YouTube.MAX_GET_QUEUE_SIZE = 1000 caps the number of videoIds that may be sent in a single request. An assert in the implementation enforces this limit.

Example

val songs = YouTube.queue(
    videoIds = listOf("dQw4w9WgXcQ", "9bZkp7q19f0")
).getOrThrow()

songs.forEach { println("${it.title}${it.id}") }

YouTube.lyrics()

Fetches the plain-text lyrics for a track using the BrowseEndpoint from NextResult.lyricsEndpoint.
suspend fun lyrics(endpoint: BrowseEndpoint): Result<String?>
endpoint
BrowseEndpoint
required
The lyrics browse endpoint. Obtain this from NextResult.lyricsEndpoint after calling next().

Returns

Result<String?> — the lyrics as a single plain-text string with newline-separated lines, or null when the track has no lyrics available.

Example

val next = YouTube.next(WatchEndpoint(videoId = "videoId")).getOrThrow()
next.lyricsEndpoint?.let { ep ->
    val lyrics = YouTube.lyrics(ep).getOrNull()
    if (lyrics != null) {
        println(lyrics)
    } else {
        println("No lyrics available")
    }
}

YouTube.transcript()

Fetches the auto-generated closed-caption transcript for a video, formatted as LRC with millisecond timestamps.
suspend fun transcript(videoId: String): Result<String>
videoId
String
required
The YouTube video ID.

Returns

Result<String> — an LRC-formatted string where each line follows the pattern [MM:SS.mmm]text, e.g.:
[00:03.480]Never gonna give you up
[00:05.840]Never gonna let you down

Example

val lrc = YouTube.transcript("dQw4w9WgXcQ").getOrThrow()
lrc.lines().forEach { println(it) }

YouTube.registerPlayback()

Reports a playback event to YouTube’s tracking endpoint. Call this after starting playback to satisfy YouTube’s analytics requirements.
suspend fun registerPlayback(
    playlistId: String? = null,
    playbackTracking: String,
): Result<*>
playlistId
String?
The playlist ID for the playback context, or null for standalone video playback.
playbackTracking
String
required
The tracking URL string from PlayerResponse.playbackTracking. The implementation automatically replaces s.youtube.com with music.youtube.com and generates a random 16-character client playback nonce (cpn) before firing the request.

Returns

Result<*> — wraps the raw HTTP response; the body is not parsed. Treat any non-failure result as success.

YouTube.getMediaInfo()

Fetches rich metadata for a video, including dislike counts via the ReturnYouTubeDislike third-party API.
suspend fun getMediaInfo(videoId: String): Result<MediaInfo>
videoId
String
required
The YouTube video ID.

Returns

Result<MediaInfo>
videoId
String
Echo of the requested video ID.
title
String?
Video title.
author
String?
Channel display name.
authorId
String?
Channel ID (e.g. "UCxxxxxx").
authorThumbnail
String?
URL of the channel avatar thumbnail.
description
String?
Full video description.
uploadDate
String?
ISO 8601 upload date string (e.g. "2009-10-25").
subscribers
String?
Formatted subscriber count (e.g. "15.8M subscribers").
viewCount
Int?
Exact view count as an integer.
like
Int?
Like count sourced from the YouTube API.
dislike
Int?
Dislike count sourced from the ReturnYouTubeDislike API. May be null if the external service is unavailable.

Example

val info = YouTube.getMediaInfo("dQw4w9WgXcQ").getOrThrow()
println("${info.title} by ${info.author}")
println("Views: ${info.viewCount}  👍 ${info.like}  👎 ${info.dislike}")

Build docs developers (and LLMs) love