Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/faraasaaay/inner/llms.txt

Use this file to discover all available pages before exploring further.

PlaybackAuthState is the central authentication state container for Inner. It holds all credential and token data and is passed through the request pipeline to produce properly authenticated HTTP headers. Both the YouTube singleton (via YouTube.authState) and PortableInnertube (via applyAuthState()) use this type to manage auth context.
import com.tamed.music.innertube.PlaybackAuthState

PlaybackAuthState fields

The raw YouTube Music cookie header string, for example "SAPISID=xxx; HSID=yyy; SSID=zzz; ...". The presence of a SAPISID key in this value determines whether hasLoginCookie returns true. Whitespace is trimmed and empty strings are converted to null during normalization.
visitorData
String?
default:"null"
The visitor identifier associated with the current session, typically starting with "Cgt" or "Cgs". This value is sent as part of the client context in every InnerTube request and is used as the sessionId when no login cookie is present.
dataSyncId
String?
default:"null"
The account identifier sent as onBehalfOfUser in authenticated browse and playback requests. Populated from the user’s account session after login. Values containing the || separator are automatically resolved during normalization — see Normalization below.
poToken
String?
default:"null"
A generic PoToken fallback. Used by both resolvePlayerPoToken() and resolveGvsPoToken() when their respective dedicated tokens (poTokenPlayer and poTokenGvs) are not set.
poTokenGvs
String?
default:"null"
A PoToken specifically for signing GVS (Google Video Server) stream URLs. When webClientPoTokenEnabled is true and the requesting client requires service integrity, this token is included in stream URL parameters. Falls back to poToken if null.
poTokenPlayer
String?
default:"null"
A PoToken for the player’s serviceIntegrityDimensions field. Required by web-family clients (WEB, WEB_REMIX, MWEB, etc.) for playback requests. Falls back to poToken if null.
webClientPoTokenEnabled
Boolean
default:"false"
Master gate for all PoToken resolution. When false, both resolvePlayerPoToken() and resolveGvsPoToken() return null regardless of other token fields. Set to true when you have valid PoTokens and want them to be included in requests.

Computed properties

true if cookie is non-null and its parsed key-value map contains the key "SAPISID". This is the primary indicator that the user is authenticated.
hasPlaybackLoginContext
Boolean
true if hasLoginCookie is true and dataSyncId is not null or blank. When both conditions are met, the full login context (cookie + account ID) is available for authenticated playback.
sessionId
String?
Returns dataSyncId when hasPlaybackLoginContext is true; otherwise returns visitorData. This is the identifier used as the active session context in requests.
fingerprint
String
A SHA-1 hash of all state fields joined with null bytes. The fingerprint changes whenever any credential field changes, making it suitable as a cache key for auth-dependent data (visitor data, stream URLs, etc.).Fields included in the hash (in order): cookie, visitorData, dataSyncId, poToken, poTokenGvs, poTokenPlayer, webClientPoTokenEnabled.

Normalization

normalized() returns a new PlaybackAuthState with all string fields sanitized:
  • Whitespace trimming — leading and trailing whitespace is stripped from every string field.
  • Empty string to null — any field that is empty or equal to the literal string "null" (case-insensitive) is converted to null.
  • dataSyncId separator resolution — when dataSyncId contains the || separator, the value is resolved as follows:
    • If the value ends with || (e.g. "abc123||"), the portion before || is used.
    • Otherwise, the portion after || is used (e.g. "||abc123""abc123").
normalized() is called automatically whenever you set individual properties on PortableInnertube (e.g. client.visitorData = "...") or call applyAuthState(). You should also call it manually if you construct a PlaybackAuthState from raw user input.
val raw = PlaybackAuthState(
    cookie = "  SAPISID=xxx; ... ",
    dataSyncId = "||user_sync_id_here",
    visitorData = "",
)
val clean = raw.normalized()
// clean.cookie  → "SAPISID=xxx; ..."
// clean.dataSyncId → "user_sync_id_here"
// clean.visitorData → null

Token resolution methods

resolvePlayerPoToken

fun resolvePlayerPoToken(
    client: YouTubeClient,
    explicitPoToken: String? = null,
): String?
Returns the PoToken to include in a player request’s serviceIntegrityDimensions. Resolution priority:
  1. explicitPoToken (if non-null and non-empty after normalization)
  2. poTokenPlayer (if webClientPoTokenEnabled is true and the client requires service integrity)
  3. poToken (fallback, same conditions)
  4. null — if webClientPoTokenEnabled is false or the client does not need service integrity

resolveGvsPoToken

fun resolveGvsPoToken(client: YouTubeClient? = null): String?
Returns the PoToken to append to GVS stream URLs. If client is provided and does not require service integrity, returns null. Otherwise resolution priority:
  1. poTokenGvs (if webClientPoTokenEnabled is true)
  2. poToken (fallback, same condition)
  3. null
Clients that require service integrity (for both methods): WEB, WEB_REMIX, WEB_CREATOR, MWEB, WEB_EMBEDDED_PLAYER, TVHTML5, TVHTML5_SIMPLY_EMBEDDED_PLAYER, TVHTML5_SIMPLY.

PlaybackAuthState.EMPTY

The default unauthenticated state. All fields are null and webClientPoTokenEnabled is false.
val state = PlaybackAuthState.EMPTY
// state.cookie           → null
// state.visitorData      → null
// state.dataSyncId       → null
// state.poToken          → null
// state.poTokenGvs       → null
// state.poTokenPlayer    → null
// state.webClientPoTokenEnabled → false
// state.hasLoginCookie   → false
// state.fingerprint      → sha1("") (constant for empty state)
Use PlaybackAuthState.EMPTY as a safe starting point or to reset auth state.

PoTokenGenerator

PoTokenGenerator is a pure Kotlin object that produces deterministic proof-of-origin tokens from a visitor identifier and client-state string. It does not require a WebView or BotGuard execution — tokens are generated locally using XOR encryption, varint encoding, and URL-safe Base64.
import com.tamed.music.innertube.utils.PoTokenGenerator

generateColdStartToken

fun generateColdStartToken(
    identifier: String,
    clientState: String = "",
): String
Generates a base PoToken for the given identifier (typically visitorData or dataSyncId) and an optional clientState string. Each call generates a fresh token with a new random 16-byte key, so repeated calls produce different tokens.
identifier
String
required
The session identifier to embed in the token — typically visitorData.
clientState
String
default:"\"\""
An optional state string that qualifies the token context. Pass "session" for session tokens or a videoId for content-specific tokens.
Returns: String — a URL-safe Base64-encoded token (without padding = characters).

generateSessionToken

fun generateSessionToken(identifier: String): String
Convenience wrapper for generateColdStartToken(identifier, clientState = "session"). Use this for poTokenPlayer — the token associated with the player session rather than a specific video.

generateContentToken

fun generateContentToken(identifier: String, videoId: String): String
Convenience wrapper for generateColdStartToken(identifier, clientState = videoId). Use this when you need a token scoped to a specific video, for example when pre-fetching stream URLs for a particular track.

Complete authentication setup example

import com.tamed.music.innertube.YouTube
import com.tamed.music.innertube.PlaybackAuthState
import com.tamed.music.innertube.utils.PoTokenGenerator

// 1. Fetch visitor data first (required as the token identifier)
val visitorData = YouTube.visitorData().getOrNull() ?: ""

// 2. Generate tokens for the current session
val playerToken = PoTokenGenerator.generateSessionToken(visitorData)
val gvsToken = PoTokenGenerator.generateColdStartToken(visitorData)

// 3. Apply the full auth state atomically
YouTube.authState = PlaybackAuthState(
    cookie = "SAPISID=xxx; HSID=yyy; SSID=zzz; ...",
    visitorData = visitorData,
    dataSyncId = "your_data_sync_id",
    webClientPoTokenEnabled = true,
    poTokenPlayer = playerToken,
    poTokenGvs = gvsToken,
).normalized()

// 4. Verify the state
val state = YouTube.authState
println("Logged in: ${state.hasLoginCookie}")
println("Session ID: ${state.sessionId}")
println("Fingerprint: ${state.fingerprint}")
To generate a content-specific token for a known video:
val videoId = "dQw4w9WgXcQ"
val contentToken = PoTokenGenerator.generateContentToken(visitorData, videoId)

// Use contentToken when signing stream URLs for this specific video
Store the authState.fingerprint alongside cached auth data. If the fingerprint changes between app sessions, invalidate any cached visitor data or stream URLs — the underlying credentials have changed and previously cached values may be stale or unauthorized.

Build docs developers (and LLMs) love